一、Angular应用中的8个主要构造块
1、模块 Modules
2、组件Components、
3、模板Templates、
4、元数据Metadata
5、数据绑定DataBinding
6、指令Directives
7、服务Service
8、依赖注入
二、模块
Angular应用是模块化的,并且Angular有自己的模块系统,他被成为Angular模块或者NgModules。
每个Angular应用至少有一个根模块,习惯上命名为AppModule。
NgModule是一个装饰器函数,他会接受一个用来描述模块属性的元数据对象,其中最重要的属性是:
1、declarations:声明本模块拥有的视图类,Angular有三种视图类,组件、指令、管道
2、export:声明declaration的子类,他可用于其他模块中的组件模板
3、imports:本模块组件模板中需要其他模块导出的类。
4、provider:服务的创建者,本模块把他们加入全局的服务表中,让他们在应用中的任何部分都能被访问到。
5、bootstrap:标示出应用的主视图,只有根模块才能设置bootstrap属性。
我们通常通过引导根模块来启动应用,我们通常在main.ts文件中来引导AppModule,
platformBrowserDynamic().bootstrapModule(AppModule);
组件负责控制屏幕上的一小块地方,我们称之为视图。
四、模板
我们通过组件的自带模板来定义视图,模板以HTML形式存在,用来告诉Angular如何渲染组件。
五、元数据
Metadata告诉Angular告诉Angular如何处理一个类。
只要把元数据附加到这个类,就相当于告诉Angular:HeroListComponent是一个组件。
在Typescript中,我们用装饰器来附加元数据,下面就是HeroListComponent的一些元数据。
@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提供基地址
2、selector:一个css选择器,他告诉Angular在父级HTML寻找一个<hero-list>标签,然后创建该组件,并插入此标签中,比如,如果应用的HTML包含<hero-list></hero-list>,Angular就会把HeroListComponent的一个实例插入这个标签中。
3、templateUrl:组件HTML的相对地址。
4、provider:一个数据,包含组件所依赖的服务所需要的服务注入商,这是在告诉Angular:该组件的构造函数需要一个HeroSerivce服务,这样组件就可以从服务中获得显示英雄列表的那些数据。
六、数据绑定个
<li>{{hero.name}}</li>
<hero-detail [hero]="selectedHero"></hero-detail>
<li (click)="selectHero(hero)"></li>
以上包含三种数据绑定的三种形式
1、{{hero.name}}:插值表达式,在标签中显示hero.name属性的值。
2、[hero]:属性绑定:把父组件selectHero的值传到子组件
3、click:事件绑定:当用户点击英雄名字时,调用组件的selectHero方法。
双向数据绑定:
这是很重要的的第四种绑定形式,他在ngModel指令这个单一标志中同时实现了属性绑定和事件绑定的功能,以下是范例。
<input [(ngModel)]="hero.name">
在双向绑定中,数据属性的值会从具有属性绑定的组件传到输入框,通过事件绑定,用户修改被传回组件,把属性值设置为新的值,Angular在每个JavaScript事件周期中一次性处理所有的数据绑定,他会从组件树的根部开始,递归处理所有子组件。
七、指令
Angular的模板是动态的,当Angular渲染他们时,他会根据指令提供的操作指南来对DOM进行修改。
指令是一个带有指令元数据的类,在typescript中,要通过@Directive装饰器把元数据附加到类上。
我们已经遇到过指令的形式之一:组件,组件是一个带模板的指令,而且@component装饰器实际上就是一个@Directive装饰器,只是扩展了一些面向模板的属性。
有两种其他类型的指令,我们称之为结构型指令和和属性型指令。他们往往像属性一样出现在元素标签中,偶尔会以名字的形式出现但多数情况还是作为赋值目标或者绑定目标实现。
结构型指令通过在DOM中添加、移除和替换元素来修改布局。
我们在范例模板中用到两个内置的结构型指令,ngFor和ngIf。
八、服务
服务分为很多种 ,包括:值、函数、以及应用所需的特性。
下面是HeroService类,用于获取数据,并通过一个已经解析的Promise返回他们。
九、依赖注入
依赖注入是提供类的新实例的一种方式,还负责处理好类所需要的全部依赖,大多数依赖还是服务,Angular也使用依赖注入提供我们需要的组件以及这些组件所需要的服务。
当Angular创建组件时,会首先为组件所需的服务找一个注入器(injector)。
注入器是一个维护服务实例的容器,存放着以前创建的实例,如果容器中没有所请求的服务实例,注入器就会创建一个服务实例,并且添加到容器中,然后把这个服务返回给Angular,当所有的服务都被解析并返回后,Angular会以这些服务为参数去调用组件的构造函数,这就是依赖注入。
如果注入器还没有服务的话,那么应该如何来创建呢?
简单来说,必须要求在注入该服务之前,把该服务的提供商provider到注入器,提供商可以创建并返回服务,通常返回的就是这个服务类本身。
我们可以在模块或者组件上注册提供商,我们通常把提供商添加到根模块,以便于使用。
或者也可以在@Component元数据中的provider属性把他注册在组件层。
@Component({
moduleId: module.id,
selector: 'hero-list',
templateUrl: 'hero-list.component.html',
providers: [ HeroService ]
})
把他注册在组件级表示该组件的每一个实例都会有一个在该组件注册的服务的新实例。
需要记住依赖注入的要点是:
(1)依赖注入渗透在整个Angular框架中,并且被到处使用。
(2)注入器是本机制的核心
(3)注册器负责维护一个容器,用于存放他创建过的服务实例
(4)注入器能使用提供商创建一个新的服务实例