角度架构
角度架构:
- Angular 概述
- 模块
- 成分
- 服务和依赖注入
Angular 架构概述
Angular 应用通常由多个 ngModule 定义,但始终有一个主模块或根模块。app.module.ts 文件是应用的引导程序所在。除根模块之外的其他模块称为功能模块。
不要忘记根模块具有导入其他模块的能力。
模块
在 Angular 应用中,你不仅仅拥有 ngModules,你还会拥有服务、组件、html 模板或 html 文件、css 文件等等。
提示:使用功能模块分离 Angular 应用是一种很好的做法。功能模块包含与该功能相关的代码,例如组件、服务、CSS 文件等。将应用分离为功能模块不仅有助于提升应用的条理性,还能帮助你实现模块的延迟加载,从而提升应用的性能😃。
来自 Angular 文档:
-声明:属于此 NgModule 的组件、指令和管道。
它们的意思是,你将把与该 ngModule 相关的功能添加到该 ngModule 下。例如,你不会把炉子添加到主卧里(也许你会,哈哈,但这是错的)。炉子应该放在厨房里。
-Exports:在其他 NgModules 的组件模板中可见且可用的声明子集。
请记住,你可以将一个 ngModule 添加到其他 ngModule 中。例如,如果你有一个 ngModule,其中包含了 Angular Material 中的所有组件,这些组件在你的应用程序的多个部分中被使用,那么你可以将它们放入一个可以被其他 ngModule 使用的 ngModule 中。
-Imports:此 NgModule 中声明的组件模板需要其导出的类的其他模块。
Providers:此 NgModule 贡献给全局服务集合的服务创建者;这些服务可在应用的所有部分访问。(您也可以在组件级别指定提供程序,这通常是首选。)
您可以通过 DI(依赖注入)在组件级别添加服务。
-Bootstrap:应用程序的主视图,称为根组件,它托管所有其他应用程序视图。只有根 NgModule 才应该设置 bootstrap 属性。
bootstrap: [AppComponent]
下面是使用其他模块时 app.module.ts(根模块)的样子的示例。
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { AppRoutingModule } from './app-routing.module';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { ReactiveFormsModule } from '@angular/forms';
import { NgrxModule } from './shared/modules/ngrx.module';
import { AppComponent } from './app.component';
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
AppRoutingModule,
HttpClientModule,
BrowserAnimationsModule,
ReactiveFormsModule,
NgrxModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {}
成分
创建新的 Angular 应用时,你会看到默认会获得一个组件:app.component.html。该组件也会默认添加到你的 app.module.ts 文件中。
组件:
1) 可以导入该组件及其视图所需的任何内容。2
) 可以容纳您的业务逻辑。3
) 可以建立组件和视图之间的连接。4
) 可以将值传递给不同的组件(父组件、兄弟组件、子组件等)。
模板、指令和数据绑定
我认为 Angular 中的模板就像拥有超能力的 HTML。模板不仅能理解 HTML,还能理解 Angular 标记,例如来自组件的指令和数据。
来自 Angular Docs,这是一个带有 Angular 标记的模板的小示例:
<h2>Hero List</h2>
<p><i>Pick a hero from the list</i></p>
<ul>
<li *ngFor="let hero of heroes" (click)="selectHero(hero)">
{{hero.name}}
</li>
</ul>
<app-hero-detail *ngIf="selectedHero" [hero]="selectedHero"></app-hero-detail>
注意:*ngIf 和 *ngFor 是指令。其中 *ngFor 是在 Angular 模板中执行循环的方式,而 *ngIf 用于有条件地显示或隐藏 HTML 元素。
在 Angular 中有多种方法可以进行数据绑定,包括:
-事件绑定:
<button (click)="gotoDetail()">View Details</button>
-单向绑定:
<h2 [innerText]="doctor.name"></h2>
-双向绑定:
<input [(ngModel)]="doctor.name"/>
-插值:
<h2>{{doctor.name}}</h2>
要了解有关数据绑定的更多信息:https://blog.eduonix.com/web-programming-tutorials/learn-different-types-data-bindings-angular-2/
得益于数据绑定,模板和组件之间可以相互通信。不仅如此,借助数据绑定,我们还可以实现不同组件之间的通信!我将在另一部分更详细地介绍组件通信。
使用模板时,您可以使用管道。管道本质上是值格式化程序。管道会更改数据的显示方式,而不会影响原始值。您可以自行构建自定义管道,也可以使用 Angular 团队创建的现有管道。
https://angular.io/api?type=pipe
来自 Angular 文档:
<!-- Default format: output 'Jun 15, 2015'-->
<p>Today is {{today | date}}</p>
服务和依赖注入
Angular 服务是具有非常明确用途的类,根据其用途创建服务是一种很好的做法。例如,如果您想创建一个服务来对员工数据进行 http 调用,那么您就不会再对汽车数据进行 http 调用。您可以为组件或功能创建多个服务。清晰地定义服务的功能,将有助于您更好地理解应用的工作原理,并帮助您更好地遵循 DRY 原则。
有两种服务:
- 功能服务:针对您正在处理的功能执行特定操作的类。
-共享服务:执行需要在多个功能之间重复使用的操作的类。
DI(依赖注入)
这是在组件内部使用我们的服务的一种方式。通过这种方式,我们允许组件访问服务类中的所有功能。
来自 Angular 文档:
对于应用中所需的任何依赖项,您都必须向应用的注入器注册一个提供程序,以便注入器可以使用该提供程序创建新的实例。对于服务而言,提供程序通常就是服务类本身。
使用服务的 DI 生命周期
当我们运行以下命令时:
ng generate service my-service-name
Angular CLI 将使用 Injectable() 装饰器创建一个服务类。这个装饰器允许我们通过 DI 在另一个类中使用该服务。
来自 Angular 文档:
注入器是主要的机制。Angular 会在启动过程中为你创建一个应用范围的注入器,并根据需要创建额外的注入器。你无需自己创建注入器。
-注入器创建依赖项并维护依赖项实例的容器,如果可能的话,它会重用该容器。
-提供者是一个告诉注入器如何获取或创建依赖项的对象。
Angular CLI 还会为服务添加一个提供程序。如果你在根级别创建一个服务,那么你刚刚创建的服务的提供程序将如下所示:
@Injectable({
providedIn: 'root',
})
是的,您可以通过在特定的 ngModule 中添加服务来更改此行为。这样做之后,该服务将仅对添加该服务的 ngModule 内的组件可用。
@NgModule({
providers: [
CarService
],
...
})
在组件中为服务执行 DI 的方法是:
//At the top of your file
import {CarService} from '../../path';
...// more code
constructor(private carService: CarService) { }
注意:您可以将 DI 用于其他事物,例如值、函数等。
要了解有关 DI 的更多信息,请查看:https://medium.com/@tomastrajan/total-guide-to-angular-6-dependency-injection-providedin-vs-providers-85b7a347b59f
文章来源:https://dev.to/devpato/angular-unofficial-docs-architecture-2d4i