Angular2

张承颜
2023-12-01

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;
  }
}
 类似资料: