1、简介
2016年9月15号,Angular2 正式版本发布。Angular2 不向下兼容 AngularJS。
Angular2 新特性:
- 移除了 controller + $scope 设计,改用组件式开发(容易上手);
- 性能更好(渲染更快,变化监测效率更高);
- 优先为移动应用设计(Angular Mobile Toolkit 套件);
- 更加贴合未来的标准(如 ES6/7、 WebComponent)
UpgradeAdapter 使得 AngularJS 和 Angular2 相互兼容。
2、Angular2 核心概念
Angular2 核心概念:
- 组件(Components)
- 元数据(MetaData)
- 模板(Templates)
- 数据绑定(Data binding)
- 服务(Services)
- 指令(Directives)
- 依赖注入(Dependency Injection)
- 模块(Modules)
2.1、组件及组件树
每个组件包含 JavaScript、 HTML、 CSS。每个组件都有各自的输入输出,用于各个组件之间通信。
组件的生命周期(部分):
- Constructor:构造器初始化
- OnChanges:第一次触发数据变化钩子(用于接收父组件传来的参数)
- OnInit:组件初始化
- OnChanges:运行期间触发数据变化钩子
- OnDestroy:组件销毁前
组件由两大部分组成:组件类和装饰器(装饰器里面是元数据)
@Component({ // 装饰器
// 元数据
selector: 'hello'; // CSS3 选择器 匹配hello标签
template: '<p>{{greeting}}</p>'; // 定义模板,可以使用 templateUrl 引入外部模板
})
export class HelloComponent{ // 组件类
private greeting: string;
constructor(){
this.greeting = 'hello';
}
}
装饰器:赋予一个类更丰富的信息(元数据)。
数据绑定:
- 插值绑定(interpolation):如上面的 greeting
属性绑定 :[value] 把组件类的数据传入到组件模板中
<input [value]="data" />
事件绑定:(keyup)把模板产生的数据通过函数调用传递给组件类
<input (keyup)="handle($event)" />
双向绑定:[(ngModel)] 实现数据的双向流动
<input [(ngModel)]="data" />
父子组件
@Component({ template: `< child [data]="item">< /child>` }) export class Parent{} @Component({ selector: 'child' }) export class Child{ @Input() data: IContact; // 子组件的输入接口,用于接收父组件的数据 }
2.2、指令
组件是自身带有模板的指令。
指令分为:
- 属性指令:改变组件模板的外观或行为,如样式等
结构指令:改变组件模板的 DOM 结构,如 ngIf 用来插入或者移除 DOM 节点。(ElementRef、Renderer 与 DOM 相关的对象)
// ngIf <input type="checkbox" [(ngModel)]="isShowMore"> <p highlight *ngIf="isShowMore"></p> // ElementRef、Renderer import { Directive, ElementRef, Renderer } from '@angular/core'; @Directive({ selector: "[highlight]" // 中括号表示指令使用在元素属性上 }) export class HighlightDirective { constructor( private el: ElementRef, private renderer: Renderer ) { renderer.setElementStyle(el.nativeElement, 'backgroundColor', 'yellow'); } } <p highlight></p>
2.3、服务
服务是实现专一目的的逻辑单元,如日志服务
export class LoggerService{
constructor(){}
debug(msg: string){}
error(msg: string){}
}
依赖注入机制是组件引入外部构建(如服务)的一种机制。服务的实例保存在依赖注入机制建立的注入器对象里。当组件需要依赖某个服务时,依赖注入机制会从注入器中查找匹配的实例,找到后并执行注入操作。当组件注入服务后,它及它的子组件都能使用该服务,并且是单例模式。
@Component({
providers: [LoggerService] // 依赖注入配置
})
export class Hello{
constructor(logger: LoggerServoce){ // 从注入器中查找LoggerService实例,找到后自动传入 LoggerService 实例
logger.debuge("OK");
}
}
分层注入:在需要改进的地方重新注入改进的服务即可。
2.4、模块
模块有两层含义:
- 框架代码以模块形式组织(文件模块)
- 功能单元以模块形式组织(应用模块)
声明模块使用 @NgModule 装饰器
@NgModule({
declarations:[],// 包装组件或指令等
providers:[], // 依赖注入
imports:[], // 导入其他模块
bootstrap:[], // 设置根组件
exports:[] // 导出组件或指令等
})
3、父子组件交互
// 子组件
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'my-child',
template: <div class="cmp-2">
<h1>子组件</h1>
<p>嘿嘿,我从父组件获取的值是:{{ message }}</p>
<button (click)="sendToParent()">发送到父组件</button>
</div>
})
export class ChildComponent {
@Input() private message: string;
@Output() private outer = new EventEmitter<string>();
constructor() { }
sendToParent() {
this.outer.emit('message from child');
}
}
//父组件
@Component({
selector: 'my-app',
templateUrl: <my-child [message]="msgToChild" (outer)="receive($event)"></my-child>
<p>从子组件获得的消息:{{ msgFromChild || '暂无' }}</p>
})
export class AppComponent {
private greeting: string;
private isShowMore: boolean;
private msgToChild: string;
private msgFromChild: string;
constructor(private logger: LoggerService) { }
ngOnInit() {
this.greeting = 'Angular 2';
this.msgToChild = 'message from parent';
this.logger.debug('应用已初始化');
}
receive(msg: string) {
this.msgFromChild = msg;
}
}