作者:农村小姑娘0 | 来源:互联网 | 2023-09-17 14:11
一、使用
@NgModule
起步
在本章中,我们将以一些坚实的项目组织练习开始,为使用 NativeScript 为 Angular 构建一个令人惊叹的应用做好准备。我们想让您深入了解一些重要且功能强大的概念,以便在规划体系结构时加以考虑,从而在考虑可伸缩性的情况下为顺利的开发体验铺平道路。
Angular 与 NativeScript 的结合提供了大量有用的范例和工具来构建和规划应用。正如人们常说的那样,强大的力量带来巨大的责任,尽管这种技术组合能够创造出令人惊叹的应用,但它们也可以用来创造一个设计过度、难以调试的应用。让我们通过几个章节来完成一些练习,您可以使用这些练习来避免常见的陷阱,并真正解锁这个堆栈的全部潜力。
我们将向您介绍 Angular 的@NgModule
decorator,我们将专门使用它来帮助将我们的应用代码组织成逻辑单元,并考虑到明确的用途和可移植性。我们还将介绍一些我们将在体系结构中使用的角度概念,例如依赖注入服务。在我们努力建立一个坚实的基础工作之后,我们将在第三年末第一次快速地运行我们的应用。
在本章中,我们将介绍以下主题:
- Angular 的 NativeScript 是什么?
- 设置本机移动应用
- 项目组织
- 建筑规划
@NgModule
装饰师
@Injectable
装饰师
- 将应用拆分为模块
心理准备
在开始编写代码之前,您可以通过规划应用所需的各种服务和功能,大大增强项目的开发体验。这样做将有助于减少代码重复,构建数据流,并为将来的快速功能开发铺平道路。
服务是通常处理处理和/或向应用提供数据的类。您对这些服务的使用不需要知道数据来自何处的细节,只需要它可以询问服务的目的,它就会发生。
素描练习
一个很好的练习是勾勒出一个应用视图的大致概念。你可能还不知道它会是什么样子,没关系;这纯粹是一个考虑用户期望的练习,作为将您的思维过程引导到您需要构建以满足这些期望的各个部分或模块的第一步。它还将帮助您思考应用需要管理的各种状态。
例如,我们将要构建的应用,TNSStudio(Telerik NativeScript(TNS))。我们将在第 2 章功能模块中深入了解我们的应用是什么以及它将做什么。
从上到下,我们可以看到带有菜单按钮、徽标和记录按钮的标题。然后,我们有一个用户录制的曲目列表,每个曲目都有一个(重新)录制按钮和一个单独或静音按钮。
从这张草图中,我们可以考虑应用可能需要提供的几种服务:
- 球员发球
- 录音服务
- 一种持久存储服务,用于记住用户为录制混音中的每个曲目设置的音量级别设置和/或用户是否经过身份验证
我们还可以了解应用可能需要管理的各种状态:
- 用户录制/曲目的列表
- 应用是否正在播放音频
- 应用是否处于录制模式
低级思维
提供一些低级服务也很有好处,这些服务提供了一个方便的 API 来访问东西,比如 HTTP 远程请求和/或日志记录。这样做将允许您创建您或您的团队在与低级 API 交互时喜欢使用的独特特性。例如,您的后端 API 可能需要为每个请求设置一个唯一的头以及一个特殊的身份验证头。围绕 HTTP 服务创建一个低级包装器将允许您隔离这些独特的特性,并为您的应用提供一个一致的 API 进行交互,以确保所有 API 调用都在一个地方得到所需的增强。
此外,您的团队可能希望能够将所有日志代码导入第三方日志分析器(用于调试或其他性能相关指标)。围绕一些框架服务创建带有精益代码的低级包装将允许您的应用快速适应这些潜在需求。
使用@NgModule 进行模块化
然后,我们可以考虑将这些服务分解为组织单元或模块。
Angular 为我们提供了@NgModule
装饰器,它将帮助我们定义这些模块的外观以及它们为我们的应用提供了什么。为了尽可能快地保持我们的应用的引导/启动时间,我们可以以这样的方式组织我们的模块,允许在我们的应用启动后延迟加载一些服务/功能。用我们的应用需要启动的所需代码的一小部分引导一个模块将有助于将此启动阶段保持在最低限度。
我们的应用的模块故障
以下是我们将如何按模块细分我们的应用组织:
- AUT0T0:低级别的服务、组件和实用程序,它们提供了一个良好的基础层。例如与日志、对话框、HTTP 和其他各种常用服务交互。
AnalyticsModule
**:您可能会有一个模块,提供各种服务来处理应用的分析。
PlayerModule
*:提供我们的应用播放音频所需的一切。
RecorderModule
*:提供我们的应用录制音频所需的一切。
()These are considered Feature Modules. (*)We will omit this module from the example in this book but wanted to mention it here for context.
模块的优点
使用类似的组织为您和您的团队提供了一些优势:
- 高可用性:通过设计一个低级别的
CoreModule
,您和您的团队有机会以独特的方式设计您喜欢如何使用常用服务,不仅是在您正在构建的应用中,而且是在未来的应用中。您可以轻松地将CoreModule
移动到一个完全不同的应用中,并在使用低级服务时获得您为此应用设计的所有相同的独特 API。
- 将您自己的应用代码视为一个‘功能模块’:这样做将帮助您专注于您的应用在
CoreModule
之外应该提供的独特功能,并减少代码的重复。
- 鼓励并增强快速开发:通过将常用功能限制在
CoreModule
中,我们减轻了在功能模块中担心这些细节的负担。我们可以简单地注入CoreModule
提供的服务,并使用这些 API,而不会重复我们自己。
- 可维护性:未来,如果由于应用需要如何与低级服务协同工作而需要更改基础细节,则只需在一个地方(在
CoreModule
服务中)进行更改,而不需要在应用的不同部分使用冗余代码。
- 性能:将您的应用拆分为模块将允许您在启动时仅加载所需的模块,然后根据需要延迟加载其他功能。最终,这将加快应用的启动时间。
考虑因素?
您可能会想,为什么不将播放器/录音机模块组合成一个模块呢?
回答:我们的应用只允许在注册用户通过身份验证后进行记录。因此,考虑认证上下文的潜力和认证用户(如果有的话)只能访问哪些特征是有益的。这将允许我们进一步微调应用的加载性能,以满足只需要时的需要。
开始
我们假设您的计算机上正确安装了 NativeScript。如果没有,请按照中的安装说明进行安装 https://nativescript.org 。安装后,我们需要使用 shell 提示符创建我们的应用框架:
tns create TNSStudio --ng
tns
代表 Telerik NativeScript。它是用于创建、构建、部署和测试任何 NativeScript 应用的主要命令行用户界面(CLI)工具。
此命令将创建一个名为TNSStudio
的新文件夹。里面是您的主项目文件夹,包括构建应用所需的所有内容。它将包含与该项目相关的所有内容。在创建项目文件夹之后,您还需要做一件事来创建一个完全可运行的应用。也就是说,添加了 Android 和/或 iOS 的运行时:
cd TNSStudio
tns platform add ios
tns platform add android
如果您使用的是 Macintosh,那么您可以同时为 iOS 和 Android 进行构建。如果您在 Linux 或 Windows 设备上运行,Android 是您可以在本地计算机上编译的唯一平台。
创建我们的模块外壳
在不编写服务实现的情况下,我们可以通过开始定义NgModule
应该提供什么来定义CoreModule
在NgModule
中的大致外观:
让我们创建app/modules/core/core.module.ts
:
// angular
import { NgModule } from '@angular/core';
@NgModule({})
export class CoreModule { }
可注入服务
现在,让我们创建服务所需的样板文件。请注意,可注入装饰器是从 Angular 导入的,以声明我们的服务将通过 Angular 的依赖项注入(DI系统)提供,该系统允许将这些服务注入可能需要它的任何类构造函数中。DI 系统提供了一种很好的方式来保证这些服务将被实例化为单例并在我们的应用中共享。还值得注意的是,如果我们不希望这些服务是单例的,而是为组件树的某些分支创建了唯一的实例,这将构成我们的用户界面,那么我们也可以在组件级别提供这些服务。不过,在本例中,我们希望将它们创建为单例。我们将在CoreModule
中添加以下内容:
LogService
:服务将我们所有的控制台登录到漏斗中。
DatabaseService
:处理我们的应用所需的任何持久数据的服务。对于我们的应用,我们将实现本机移动设备的存储选项,例如应用设置,作为一个简单的键/值存储。但是,您可以在这里实施更高级的存储选项,例如通过 Firebase 进行远程存储。
**创建app/modules/core/services/log.service.ts
:
// angular
import { Injectable } from '@angular/core';
@Injectable()
export class LogService {
}
另外,创建app/modules/core/services/database.service.ts
:
// angular
import { Injectable } from '@angular/core';
@Injectable()
export class DatabaseService {
}
一致性和标准
为了保持一致性,减少导入的长度,并为更好的可扩展性做好准备,我们还将在app/modules/core/services
中创建一个index.ts
文件,该文件将导出const
服务集合,并导出这些服务(按字母顺序排列,以保持整洁):
import { DatabaseService } from './database.service';
import { LogService } from './log.service';
export const PROVIDERS: any[] = [
DatabaseService,
LogService
];
export * from './database.service';
export * from './log.service';
在本书中,我们将遵循类似的组织模式。
最终确定核心模块
我们现在可以修改我们的CoreModule
以使用我们已经创建的内容。我们还将借此机会导入NativeScriptModule
,我们的应用需要与其他 NativeScript 配合使用,以实现角度功能,我们希望我们的应用能够在全球范围内访问这些功能。因为我们知道我们需要这些功能,所以在全球范围内,我们也可以指定它们是导出的,所以当我们导入并使用我们的CoreModule
时,我们不需要担心在其他地方导入NativeScriptModule
。以下是我们对CoreModule
的修改:
// nativescript
import { NativeScriptModule } from 'nativescript-angular/nativescript.module';
// angular
import { NgModule } from '@angular/core';
// app
import { PROVIDERS } from './services';
@NgModule({
imports: [
NativeScriptModule
],
providers: [
...PROVIDERS
],
exports: [
NativeScriptModule
]
})
export class CoreModule { }
我们的CoreModule
现在有了一个良好的起步基础,我们将在下面的章节中具体实施。
总结
在本章中,我们为我们的应用创建了坚实的基础。您学会了如何从模块的角度思考应用的体系结构。您还学习了如何利用 Angular 的@NgModule
装饰器来构建这些模块。最后,我们现在有了一个很好的基础架构,可以在上面构建我们的应用。
现在,您已经掌握了一些关键概念,我们现在可以进入我们应用的核心功能模块。让我们深入了解我们应用的主要功能,继续在第 2 章、功能模块中构建我们的服务层。我们将很快为我们的应用创建一些视图,并在第 3 章中的 iOS 和 Android 上运行该应用,我们通过组件构建的第一个视图。**