一、基本构造块
如何写应用:
用Angular扩展语法编写HTML模板,用组件类管理这些模板,用服务添加应用逻辑,用模块打包发布组件与组件。
然后我们通过引导根模块来启动该应用,Angular在浏览器中接管展现应用,并根据提供的操作指令响应用户的交互。
二、模块
Angular应用是模块化的,并且Angular有自己的模块系统,他被称为Angular模块或者NgModules。
每个Angular应用至少有一个根模块,习惯上命名AppModule。
Angular模块都是一个带有@NgModule装饰器的类。
装饰器是用来修饰JavaScript类的函数,Angular有很多装饰器,他们负责把元数据附加到类上,以了解那些类的设计意图以及他们应该如何工作。
NgModule是一个装饰器函数,他接收一个用来描述模块属性的元数据对象,其中最重要的属性有:
(1)declarations:声明本模块拥有的视图类,Angular有三种视图类:组件、指令和管道。
(2)exports:declaration的子集,可用于其他模块的组件模板。
(3)imports:本模块声明的组件模板需要的类所在的其他模块。
(4)providers:服务的创建者,并加入到全局服务列表中,可用于应用任何部分。
(5)bootstrap:指定应用的主视图,他是所有其他视图的宿主,只有根模块才能设置bootstrap。
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
@NgModule({
imports: [ BrowserModule ],
providers: [ Logger ],
declarations: [ AppComponent ],
exports: [ AppComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
我们通过引导根模块来启动应用,在开发期间,你通常在一个main.ts中引导AppModule:
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
platformBrowserDynamic().bootstrapModule(AppModule);
三、Angular模块库
Angular提供了一组JavaScript模块,可以把他们看成库模块。
每个Angular库的名字都有@angular前缀。
用npm包管理工具安装他们,并用JavaScript的import语句导入其中一部分部件。
例如:
import { Component } from '@angular/core';
或者在应用中需要BrowserModule一部分素材,那么你就需要把他加入@NgModule元数据的import中
imports: [ BrowserModule ],
四、组件
组件负责控制屏幕上的一部分区域,我们称之为视图。
我们在类中定义组件的应用逻辑,为视图提供支持,组件通过一些由属性和方法组成的api与视图交互。
当用户在这个应用中浏览时,Angular会创建、更新和销毁组件。
五、模板
通常我们用组件自带的模板来定义组件视图,模板以HTML的形式存在,告诉Angular如何渲染组件。
六、元数据
Metadata元数据告诉Angular如何处理一个类。
要告诉Angular某个类是组件,只要把元数据附加到这个类。
在TypeScript中,我们用装饰器来附加元数据,下面就是一些元数据。
@Component({
moduleId: module.id,
selector: 'hero-list',
templateUrl: 'hero-list.component.html',
providers: [ HeroService ]
})
export class HeroListComponent implements OnInit {
/* . . . */
}
这里能看到@Component装饰器,他把紧随其后的类标记成了组件类。
@Component装饰器能接受一个配置对象,Angular能基于这些信息创建和展示视图。
@Component的配置项包括
(1)moduleId:为与模块相关的URL(如templateUrl)提供基地址。
(2)selector:css选择器,他告诉Angular在父级HTML中查找hero-list标签,创建并插入该标签。例如,如果应用的HTML中包含hero-list这个标签,Angular就会把HeroListComponent的一个实例插入到这个标签中。
(3)templateUrl:组件HTML模板的模块相对地址。
(4)providers:组件所需服务的依赖注入提供商数组,这是在告诉Angular:该组件的构造函数需要HeroService服务。
@Component里面的元数据会告诉Angular从哪里获取你为组件指定的主要构造块。
模板、元数据和组件共同描绘出这个视图。
其他元数据装饰器用类似的方式来指导Angular的行为。
如@Injectable、@Input和@output等是一些最常用的装饰器。
七、数据绑定
Angular支持数据绑定
HeroListComponent中有三种方式:
<li>{{hero.name}}</li>
<hero-detail [hero]="selectedHero"></hero-detail>
<li (click)="selectHero(hero)"></li>
(1){{hero.name}}插值表达式显示hero.name的值。
(2)[hero]属性绑定把selectedHero的值传到组件中。
(3)click事件绑定
双向数据绑定是重要的第四种绑定形式,他使用了ngModel指令组合了属性绑定和事件绑定功能,下面是范例:
<input [(ngModel)]="hero.name">
八、指令
Angular是动态的,当Angular渲染他们的时候,他们会根据指令提供的操作对DOM进行转换。
指令是带有指令元数据的类, 在TypeScript中,要通过@Directive装饰器把元数据附加到类上。
组件是一个带模板的指令,@Component装饰器实际上就是一个@Directive装饰器,只是扩展了一些面向模板的属性。
还有两种其他类型的指令,结构型指令和属性型指令。
结构型指令通过在DOM中添加和移除和替换元素来修改布局。
<li *ngFor="let hero of heroes"></li>
<hero-detail *ngIf="selectedHero"></hero-detail>
属性型指令修改一个现有元素的外观或行为。
ngModel指令就是属性型指令的一个例子,他实现了双向数据绑定。
九、服务
服务是一个广义范畴,包括值、函数或应用所需特性。
组件类应该保持精简,组件本身不从服务器获得数据,不进行验证输入,也不往控制台写日志,他们把这些任务委托给服务。
十、依赖注入
依赖注入是提供类的新实例的一种方式,还负责处理好类所需的依赖,大多数依赖都是服务,Angular使用依赖注入来提供新组件以及组件所需的服务。
当Angular创建组件时,会首先为组件所需的服务请求一个注入器(injector),注入器维护了一个服务器实例的容器,如果所请求的服务实例不在容器中,注入器就会创建一个服务实例,并且添加到容器中,然后返回给Angular,当所有请求的服务都被解析完成后,Angular会以这些服务为参数调用组件的构造函数,这就是依赖注入。
如果注入器还没有HeroService,他怎么知道该如何创建一个呢?
简单来说,必须在注入HeroService之前,在注入器中注册HeroService的提供商provider,提供商用于创建并返回一个服务,通常是服务本身。
我们可以在模块或者组件中注册提供商。
通常会把提供商添加到根模块上,以便在任何地方使用服务的同一个实例。
providers: [
BackendService,
HeroService,
Logger
],
或者也可以在@Component元数据中的providers属性中把他注册在组件层。
@Component({
moduleId: module.id,
selector: 'hero-list',
templateUrl: 'hero-list.component.html',
providers: [ HeroService ]
})
把他注册在组件级表示该组件的每一个新实例都会有一个服务的新实例。
依赖注入的要点:
(1)注入器是本机制的核心
注入器维护一个容器,用来存放他创建过的服务实例。
注入器能使用提供商创建一个新的服务实例
(2)提供商是用于创建服务的配方。
(3)把提供商注册到注入器。
十一、其他
1、动画
用Angular的动画库让组件动起来,而不需要对动画技术和css有深入的了解。
2、变更检测
变更检测文档会告诉你Angular是如何决定组件的属性值变化,什么时候应该更新到屏幕,以及他是如何利用区域(zone)来拦截异步活动并执行变更检测策略。
3、事件
事件文档将会告诉你如何使用组件和服务触发支持发布和订阅的事件。
4、表单
通过基于HTML的验证和脏检查机制支持复杂的数据输入场景。
5、HTTP
通过HTTP客户端,可以与服务器通讯接收数据。
6、生命周期
7、管道
8、路由器
在应用程序客户端间的页面进行导航,并且不离开浏览器
9、测试
使用Angular测试平台,在你的应用部件与Angular框架交互时进行单元测试。