Angular 2 Input

更新時間 - 2017-03-22html

Input 是屬性裝飾器,用來定義組件內的輸入屬性。在實際應用場合,咱們主要用來實現父組件向子組件傳遞數據。Angular 應用是由各式各樣的組件組成,當應用啓動時,Angular 會從根組件開始啓動,並解析整棵組件樹,數據由上而下流下下一級子組件。typescript

圖片描述

@Input()

counter.component.tssegmentfault

import { Component, Input } from '@angular/core';

@Component({
    selector: 'exe-counter',
    template: `
      <p>當前值: {{ count }}</p>
      <button (click)="increment()"> + </button>
      <button (click)="decrement()"> - </button>
    `
})
export class CounterComponent {
    @Input() count: number = 0;

    increment() {
        this.count++;
    }

    decrement() {
        this.count--;
    }
}

app.component.ts瀏覽器

import { Component } from '@angular/core';

@Component({
  selector: 'exe-app',
  template: `
   <exe-counter [count]="initialCount"></exe-counter>
  `
})
export class AppComponent {
  initialCount: number = 5;
}

以上代碼運行後瀏覽器顯示的結果:app

圖片描述

@Input('bindingPropertyName')

Input 裝飾器支持一個可選的參數,用來指定組件綁定屬性的名稱。若是沒有指定,則默認使用 @Input 裝飾器,裝飾的屬性名。具體示例以下:ide

counter.component.ts函數

import { Component, Input } from '@angular/core';

@Component({
    selector: 'exe-counter',
    template: `
      <p>當前值: {{ count }}</p>
      <button (click)="increment()"> + </button>
      <button (click)="decrement()"> - </button>
    `
})
export class CounterComponent {
    @Input('value') count: number = 0;
    ... // 其他代碼未改變
}

app.component.tsui

import { Component } from '@angular/core';

@Component({
  selector: 'exe-app',
  template: `
   <exe-counter [value]="initialCount"></exe-counter>
  `
})
export class AppComponent {
  initialCount: number = 5;
}

@Component() - inputs

import { Component, Input } from '@angular/core';

@Component({
    selector: 'exe-counter',
    template: `
      <p>當前值: {{ count }}</p>
      <button (click)="increment()"> + </button>
      <button (click)="decrement()"> - </button>
    `,
    inputs:['count:value'] // 類成員屬性名稱:綁定的輸入屬性名稱
})
export class CounterComponent {

    count: number = 0;

    increment() {
        this.count++;
    }

    decrement() {
        this.count--;
    }
}

setter & getter

setter 和 getter 是用來約束屬性的設置和獲取,它們提供了一些屬性讀寫的封裝,可讓代碼更便捷,更具可擴展性。經過 setter 和 getter 方式,咱們對類中的私有屬性進行了封裝,能避免外界操做影響到該私有屬性。此外經過 setter 咱們還能夠封裝一些業務邏輯,具體示例以下:this

counter.component.tsspa

import { Component, Input } from '@angular/core';

@Component({
    selector: 'exe-counter',
    template: `
      <p>當前值: {{ count }} </p>
      <button (click)="increment()"> + </button>
      <button (click)="decrement()"> - </button>
    `
})
export class CounterComponent {
    _count: number = 0; // 默認私有屬性如下劃線開頭,不是必須也可使用$count
    biggerThanTen: boolean = false;

    @Input()
    set count (num: number) {
        this.biggerThanTen = num > 10;
        this._count = num;
    }

    get count(): number {
        return this._count;
    }

    increment() {
        this.count++;
    }

    decrement() {
        this.count--;
    }
}

ngOnChanges

當數據綁定輸入屬性的值發生變化的時候,Angular 將會主動調用 ngOnChanges 方法。它會得到一個 SimpleChanges 對象,包含綁定屬性的新值和舊值,它主要用於監測組件輸入屬性的變化。具體示例以下:

import { Component, Input, SimpleChanges, OnChanges } from '@angular/core';

@Component({
    selector: 'exe-counter',
    template: `
      <p>當前值: {{ count }}</p>
      <button (click)="increment()"> + </button>
      <button (click)="decrement()"> - </button>
    `
})
export class CounterComponent implements OnChanges{
    @Input() count: number = 0;

    ngOnChanges(changes: SimpleChanges) {
        console.dir(changes['count']);
    }

    increment() {
        this.count++;
    }

    decrement() {
        this.count--;
    }
}

以上代碼運行後瀏覽器顯示的結果:

圖片描述

上面例子中須要注意的是,當手動改變輸入屬性的值,是不會觸發 ngOnChanges 鉤子的。

我有話說

1.在構造函數中是獲取不到輸入屬性的值

在子組件的構造函數中,是沒法獲取輸入屬性的值,只能在 ngOnChanges 或 ngOnInit 鉤子中獲取到。由於子組件的構造函數會優先執行,當子組件輸入屬性變化時會自動調用 ngOnChanges 鉤子,而後在調用 ngOnInit 鉤子,因此在 ngOnInit 鉤子內能獲取到輸入的屬性。

具體詳情可參考 - Angular 2 constructor & ngOnInit

2.不能同時使用 @Input 裝飾器 或在 @Directive、@Component inputs 字段中定義同一個輸入屬性,具體示例以下:

@Component({
    selector: 'exe-counter',
    inputs:['count:value'] 
})
export class CounterComponent {
    @Input('value') count: number = 0;
}

3.@Input vs inputs

相同點:

  • 它們都是用來定義輸入屬性

異同點:

  • inputs 定義在指令的 metadata 信息中,開發者對指令的輸入屬性一目瞭然。此外對於未選用 TypeScript 做爲開發語言的開發者,也只能在 metadata 中定義指令的輸入屬性。

  • @Input 屬於屬性裝飾器,經過它咱們能夠一塊兒定義屬性的訪問描述符 (public、private、protected):

@Input() public attr: string;

4.輸入、輸出屬性風格指南

4.1 堅持使用 @Input 和 @Output ,而非 @Directive 和 @Component 裝飾器的 inputs 和 outputs 屬性:

  • 易於在類裏面識別哪些屬性是輸入屬性或輸出屬性。

4.2 堅持把 @Input 或者 @Output 放到所裝飾的屬性的同一行:

  • 若是須要重命名與@Input或者@Output關聯的屬性或事件名,你能夠在一個位置修改。

4.3 避免爲輸入和輸出屬性指定別名

  • 同一個屬性有兩個名字(一個對內一個對外)很容易致使混淆。

詳細信息請參考 - Angular 2 風格指南 - STYLE 05-12

5.項目開發中儘可能經過 @Input 裝飾器定義無狀態的組件,即組件僅依賴於輸入屬性,這樣會大大提升組件可複用性

相關文章
相關標籤/搜索