开源中国博客地址
简述:组件(component)是构成Angular应用的基础和核心.可以这样说,组件用来包装特定的功能,应用程序的有序运行依赖于组件之间的协同工作.
1. 组件化标准:W3C为了统一组件化的标准方式,提出了Web Component的标准.通过标准化的非侵入方式封装组件,每个组件包含自己的HTML,CSS,JavaScript代码,
并且不会对页面上其他组件产生影响.Web Component是由一些新技术构成的,还提供了浏览器原声的UI组件标准,所以不需要引入任何外部的依赖.要使用一个已有的
Web Component组件,仅需如下添加一行导入声明,如:
Web Component标准包括如下四个重要的概念:
1.自定义元素:这个特性允许创建自定义的HTML标记和元素,每个元素都有属于自己的脚本和样式.
2.模板:模板允许使用标签去预先定义一些内容,但并不随页面加载而渲染,而是可以在运行时使用JavaScript去初始化它.
3.Shadow DOM:通过Shadow DOM可以在文档流中创建一些完全独立于其他元素的DOM子树,这个特性可以让开发者开发一个独立的组件,并且不会干扰到其他DOM元素.
4.HTML导入:一种在HTML文档中引入其他HTML文档的方法,用于导入Web Component的机制.
注意:目前仅有Chrome浏览器对该标准支持最高,其他主流浏览器并未完全实现Web Component标准.
有关Web Component标准的更多信息可待以后研究,这里并不深究.
2. Angular组件:在Angular中引入了视图包装(ViewEncapsulation)的概念,允许通过设置ViewEncapsulation.Native选项来使用原生的Shadow DOM.Angular还支持模板,
自定义标签,异步加载组件等.Angular组件是自描述的--可以和宿主元素交互,知道如何以及合适渲染自己,可配置注入服务,有明确的Input和Output定义.所有Angular的组件都可以
独立存在,都可以作为根组件被引导,也可以被路由加载,或者在其他组件中使用.不过一个组件不能单独被启用,它必须被包装到模块(NgModule)中.
组件是Angular应用的最小的逻辑单元,模块则是在组件之上的一层抽象.组件以及其他部件,如指令,管道,服务,路由等都可以被包含到一个模块中.外部引用通过引用这个模块来使用
一系列封装好的功能.
3. 创建组件的步骤:
1.从@angular/core中引入Component装饰器.
2.建立一个普通的类,并用@Component修饰它.
3.在@Component中,设置selector自定义标签和template模板.
4. 组件装饰器:@Component是TypeScript的语法,它是一个装饰器,任何一个Angular组件类都会用这个装饰器修饰,组件类最终编译成的JavaScript代码如下:
var ContactItemComponent=(function(){
function ContactItemComponent(){};
ContactItemComponent=__decorate([core_1.Component({
selector:'contact-item',
template:`
xzm
13648301556
5. 组件元数据:
5.1 selector:是用于定义组件在HTML代码中匹配的标签,它将称为组件的命名标记.通常情况下都需要设置selector,特俗情况可以忽略,不指定时设置默认为匹配div元素.
selector的命名方式建议使用"烤肉串式"命名,即采用小写字母并以-分隔.
5.2 template是为组件指定一个内联模板.内联模板建议使用ES6的多行字符串``(两个反引号),这样可创建多行.
5.3 templateUrl:是为组件指定一个外部模板的URL地址.
5.4 styles:是为组件制定内联样式,如:
@Component({
styles:[`
li:last-child{
border-bottom:none;
}
`]
})
5.5 styleUrls:是为组件指定一系列用于该组件的外联样式表文件,如:
@Component({
styleUrls:['app/list/item.component.css']
})
注意:styles和styleUrls允许同时指定.同时指定,styles中的样式会被先解析,也就是styles的样式会被styleUrls的覆盖.
6. 模板:每个组件都必须设置一个模板,angular才能将组件内容渲染到DOM上,这个DOM元素就是宿主元素.组件可以与宿主元素交互,交互的形式如下:
1.显示数据
2.双向数据绑定
3.监听宿主元素事件以及调用组件方法.
6.1 显示数据:可以使用插值语法{{}}来显示组件的数据.
6.2 双向数据绑定,使用[(ngModule)]='property'的语法.
6.3监听宿主元素事件及调用组件方法:()是Angular提供的事件绑定语法糖,通过(eventName)的方式可以轻易地响应UI事件.
7. 组件和模块:Angular提供了@NgModule装饰器来创建模块,一个应用可以有多个模块,但只有一个根模块(RootModule),其他模块叫作特性模块(FeatureModule).根模块是启动应用
的入口模块,根模块必须通过bootstrap元数据来指定应用的根组件,然后通过bootstrapModule()方法来启动应用.
7.1 NgModule主要的元素居如下:
1.declarations:用于指定属于这个模块的是视图类(View Class),即指定那些部件组成了这个模块.Angular又组件,指令和管道三种视图类,这些视图类只能属于一个模块,必须
注意不能再次声明属于其他模块的类.
2.exports:导出视图类.当该模块被引入到外部模块时,这个属性指定了外部模块可以使用该模块的那些视图类,所以它的值类型跟declarations一致.
3.imports:引入该模块依赖的其他模块或路由,引入后模块里的组件模板才能引用外部对应的组件,指令和管道.
4.providers:指定模块依赖的服务,引入后该模块中的所有组件都可以使用这些服务.
7.2 导出视图类以及导入依赖模块:有时候模块中的组件,指令或管道,可能也会在其他模块中使用,这时可以使用exports元数据对外暴露这些组件,指令或管道.而相对应的,如果在一个模块
中想要使用其他模块对外暴露的组件,服务等,除了需要在模块的文件头使用import from导入模块,同时还要在NgModule的元数据import中为该模块制定要导入的依赖模块,这其中的
两个导入(import),前一个是TypeScript的模块导入,后一个是Angular框架的模块导入,希望这里不要混淆了.
7.3 服务引入:
引入服务有两种方式:
1.通过@NgModule的providers引入,通过它引入的服务,在模块的所有组件都可以使用.
2.通过@Component的providers引入,通过它引入的服务,在组件及其子组件中都可以共用这些引入的服务.
8. 组件交互:组件交互就是组件通过一定的方式来访问其他组件的属性或方法,从而实现数据的双向流通.组件交互有很多种方式,非父子关系的组件可通过服务来实现数据交互通信.
8.1 组件的输入输出属性:Angular除了提供@Input和@Output装饰器语法来处理组件数据的流入流出外,还提共了在组件的元数据中使用inputs,outputs来设置输入输出属性,设置的值必须
为字符串数组,元素的名称需要和成员变量相对应.
如:
@Component({
inputs:['contact'], //'contact' 匹配成员变量contact
outputs['routerNavigate']
})
8.2 父组件向子组件传递数据:父组件的数据是通过子组件的输入属性流入子组件,在子组件完成接收或者拦截,从而实现了数据由上而下的传递.
Angular会从根组件开始启动,并解析整棵组件树,数据以由上而下的方式流向下一级子组件.不过需要注意的是,目标组件的属性必须通过输入属性(@Input)明确的标记才能接收到来自
父组件的数据.
8.3 拦截输入数据:子组件可以拦截输入属性的数据并进行相应的处理.
有如下两种方式:
1.setter拦截输入属性:getter和setter通常一起使用,用来对属性进行相关约束.它们提供了对属性读写的封装,使代码结构更清晰,更具可扩展性.setter可对属性进行再封装
处理,对复杂的内部逻辑通过访问权限控制来隔绝外部调用,以避免外部的错误调用影响到内部的状态.同时也要把内部复杂的逻辑结构封装成高度抽象可被简单调用的属性,再通过
getter返回要设置的属性值,方便调用者使用.
setter拦截器示例,如:
@Component({
selector:'list-item',
template:`
collectTheContact(){
this.contactCollect.collectTheContact();
}
}
9. 组件内容嵌入:内容嵌入(ng-content)是组件的一个高级功能特性,使用组件的内容嵌入特性能很好的扩从组件的功能,方便代码的复用.内容嵌入通常用来创建可复用的组件,典型的例子
是模态对话框或导航栏.
示例如:
import { Component } from '@angular/core';
@Component({
selector:'example-content',
template:`
10. 组件的生命周期:组件的生命周期由Angular内部管理,从组件的创建,渲染,到数据变动事件的触发,再到组件从DOM中移除,Angular都提供了一系列的钩子.
10.1 生命周期的钩子:开发者可以实现一个或者多个生命周期钩子(接口),从而在生命周期的各阶段做出适当的处理.这些钩子包含在@Angular/core中,
以下是组件常用的生命周期钩子:
1.ngOnChanges:它是用来响应组件输入值(通过@Input装饰去显式指定的变量)发生变化时触发的事件,接收一个SimpleChanges对象,包含当前值和变化前值,
该方法在ngOnInit之前.
2.ngOnInit:用于数据绑定输入性之后初始化组件,该钩子方法会在第一次ngOnChanges之后被调用.使用ngOnInit有以下两个重要原因:
a.组件构造后不久需要进行复杂的初始化.
b.需要在输入属性设置完成之后才构建组件.
3.ngDoCheck:用于变化监测,该钩子方法会在每次变化监测发生时被调用.每一个变化监测周期内,不管数据值是否发生变化,ngDoCheck都会被调用,该方法需要慎用,
如鼠标移动触发mousemove事件
4.ngAfterContentInit:在组件使用
5.ngAfterContentChecked:在组件使用了
ngAfterContentChecked.
6.ngAfterViewInit:会在Angular创建了组件的视图及其子组件视图之后被调用.
7.ngAfterViewChecked:在Angular创建了组件的视图及其子组件视图之后被调用一次,并且在每次子组件变化监测时也会被调用.
8.ngOnDestroy:在销毁指令/组件之前触发.那些不会被垃圾回收器自动回收的资源都应当在ngOnDestory中手动销毁.