Angular中Input和Output有什么用-創(chuàng)新互聯(lián)

這篇文章將為大家詳細(xì)講解有關(guān)Angular中Input和Output有什么用,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

專注于為中小企業(yè)提供成都網(wǎng)站制作、成都網(wǎng)站建設(shè)、外貿(mào)營銷網(wǎng)站建設(shè)服務(wù),電腦端+手機端+微信端的三站合一,更高效的管理,為中小企業(yè)吳橋免費做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動了1000多家企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網(wǎng)站建設(shè)實現(xiàn)規(guī)模擴充和轉(zhuǎn)變。

Input 是屬性裝飾器,用來定義組件內(nèi)的輸入屬性。在實際應(yīng)用場合,我們主要用來實現(xiàn)父組件向子組件傳遞數(shù)據(jù)。Angular 應(yīng)用是由各式各樣的組件組成,當(dāng)應(yīng)用啟動時,Angular 會從根組件開始啟動,并解析整棵組件樹,數(shù)據(jù)由上而下流下下一級子組件。

@Input()

counter.component.ts
import { Component, Input } from '@angular/core';
@Component({
    selector: 'exe-counter',
    template: `
      <p>當(dāng)前值: {{ 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;
}

@Input(‘bindingPropertyName’)

Input 裝飾器支持一個可選的參數(shù),用來指定組件綁定屬性的名稱。如果沒有指定,則默認(rèn)使用 @Input 裝飾器,裝飾的屬性名。具體示例如下:

counter.component.ts

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

app.component.ts

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

setter & getter

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

counter.component.ts

import { Component, Input } from '@angular/core';
@Component({
    selector: 'exe-counter',
    template: `
      <p>當(dāng)前值: {{ count }} </p>
      <button (click)="increment()"> + </button>
      <button (click)="decrement()"> - </button>
    `
})
export class CounterComponent {
    _count: number = 0; // 默認(rèn)私有屬性以下劃線開頭,不是必須也可以使用$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

當(dāng)數(shù)據(jù)綁定輸入屬性的值發(fā)生變化的時候,Angular 將會主動調(diào)用 ngOnChanges 方法。它會獲得一個 SimpleChanges 對象,包含綁定屬性的新值和舊值,它主要用于監(jiān)測組件輸入屬性的變化。具體示例如下:

import { Component, Input, SimpleChanges, OnChanges } from '@angular/core';
@Component({
    selector: 'exe-counter',
    template: `
      <p>當(dāng)前值: {{ 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--;
    }
}

上面例子中需要注意的是,當(dāng)手動改變輸入屬性的值,是不會觸發(fā) ngOnChanges 鉤子的。

Output 是屬性裝飾器,用來定義組件內(nèi)的輸出屬性。前面我們介紹了 Input 裝飾器的作用,也了解了當(dāng)應(yīng)用啟動時,Angular 會從根組件開始啟動,并解析整棵組件樹,數(shù)據(jù)由上而下流下下一級子組件。而我們今天介紹的 Output 裝飾器,是用來實現(xiàn)子組件將信息通過事件的形式通知到父級組件。

在介紹 Output 屬性裝飾器前,我們先來介紹一下 EventEmitter 這個幕后英雄。它用來觸發(fā)自定義事件,具體使用示例如下:

let numberEmitter: EventEmitter<number> = new EventEmitter<number>(); 
numberEmitter.subscribe((value: number) => console.log(value));
numberEmitter.emit(10);

在 Angular 中的 EventEmitter 應(yīng)用場景是:

子指令創(chuàng)建一個 EventEmitter 實例,并將其作為輸出屬性導(dǎo)出。子指令調(diào)用已創(chuàng)建的 EventEmitter 實例中的 emit(payload) 方法來觸發(fā)一個事件,父指令通過事件綁定 (eventName) 的方式監(jiān)聽該事件,并通過 $event 對象來獲取 payload 對象。是不是感覺有點抽象,我們馬上實戰(zhàn)一下。

@Output()

counter.component.ts
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
    selector: 'exe-counter',
    template: `
      <p>當(dāng)前值: {{ count }}</p>
      <button (click)="increment()"> + </button>
      <button (click)="decrement()"> - </button>
    `
})
export class CounterComponent {
    @Input() count: number = 0;
    @Output() change: EventEmitter<number> = new EventEmitter<number>();
    increment() {
        this.count++;
        this.change.emit(this.count);
    }
    decrement() {
        this.count--;
        this.change.emit(this.count);
    }
}

app.component.ts

import { Component } from '@angular/core';
@Component({
  selector: 'exe-app',
  template: `
   <p>{{changeMsg}}</p> 
   <exe-counter [count]="initialCount" 
    (change)="countChange($event)"></exe-counter>
  `
})
export class AppComponent {
  initialCount: number = 5;
  changeMsg: string;
  countChange(event: number) {
    this.changeMsg = `子組件change事件已觸發(fā),當(dāng)前值是: ${event}`;
  }
}

@Output(‘bindingPropertyName’)

Output 裝飾器支持一個可選的參數(shù),用來指定組件綁定屬性的名稱。如果沒有指定,則默認(rèn)使用 @Output 裝飾器,裝飾的屬性名。具體示例如下:

counter.component.ts

import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
    selector: 'exe-counter',
    template: `
      <p>當(dāng)前值: {{ count }}</p>
      <button (click)="increment()"> + </button>
      <button (click)="decrement()"> - </button>
    `
})
export class CounterComponent {
    @Input() count: number = 0;
    @Output('countChange') change: EventEmitter<number> = new EventEmitter<number>();
... // 其余代碼未改變
}

app.component.ts

import { Component } from '@angular/core';
@Component({
  selector: 'exe-app',
  template: `
   <p>{{changeMsg}}</p> 
   <exe-counter [count]="initialCount" 
    (countChange)="countChange($event)"></exe-counter>
  `
})
export class AppComponent {
  initialCount: number = 5;
  changeMsg: string;
  countChange(event: number) {
    this.changeMsg = `子組件change事件已觸發(fā),當(dāng)前值是: ${event}`;
  }
}

雙向綁定

在介紹雙向綁定之前,我們先來說個需求:即在 CounterComponent 子組件 count 值發(fā)生變化的時候,需同步更新 AppComponent 父組件中的 initialCount 的值。通過上面的實例,我們知道我們可以在 AppComponent 父組件中監(jiān)聽 CounterComponent 子組件的 change 事件,然后在 change 事件中更新 initialCount 的值。具體示例如下:

counter.component.ts

import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
    selector: 'exe-counter',
    template: `
      <p>子組件當(dāng)前值: {{ count }}</p>
      <button (click)="increment()"> + </button>
      <button (click)="decrement()"> - </button>
    `
})
export class CounterComponent {
    @Input() count: number = 0;
    @Output() change: EventEmitter<number> = new EventEmitter<number>();
    increment() {
        this.count++;
        this.change.emit(this.count);
    }
    decrement() {
        this.count--;
        this.change.emit(this.count);
    }
}

app.component.ts

import { Component } from '@angular/core';
@Component({
  selector: 'exe-app',
  template: `
   <p>父組件當(dāng)前值:{{ initialCount }}</p> 
   <exe-counter [count]="initialCount" 
    (change)="initialCount = $event"></exe-counter>
  `
})
export class AppComponent {
  initialCount: number = 5;
}

其實雙向綁定是由兩個單向綁定組成:

模型 -> 視圖數(shù)據(jù)綁定

視圖 -> 模型事件綁定

Angular 中 [] 實現(xiàn)了模型到視圖的數(shù)據(jù)綁定,() 實現(xiàn)了視圖到模型的事件綁定。把它們兩個結(jié)合在一起 [()] 就實現(xiàn)了雙向綁定。也被稱為 banana in the box 語法。

[()] 語法示例

counter.component.ts

import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
    selector: 'exe-counter',
    template: `
      <p>子組件當(dāng)前值: {{ count }}</p>
      <button (click)="increment()"> + </button>
      <button (click)="decrement()"> - </button>
    `
})
export class CounterComponent {
    @Input() count: number = 0;
    // 輸出屬性名稱變更: change -> countChange
    @Output() countChange: EventEmitter<number> = new EventEmitter<number>();
    ... // 其余代碼未改變
}

app.component.ts

import { Component } from '@angular/core';
@Component({
  selector: 'exe-app',
  template: `
   <p>父組件當(dāng)前值:{{ initialCount }}</p> 
   <exe-counter [(count)]="initialCount"></exe-counter>
  `
})
export class AppComponent {
  initialCount: number = 5;
}

從上面可以看出,[(modelName)] 可以拆分成兩部分 modelName 和 modelNameChange ,[modelName] 用于綁定輸入屬性,(modelNameChange) 用于綁定輸出屬性。當(dāng) Angular 在解析模板時,遇到 [(modelName)] 形式的綁定語法,它會期待這個指令中會存在一個名為 modelName 的輸入屬性和一個名為 modelNameChange 的輸出屬性。

ngModel

使用過 Angular 1.x 的讀者,應(yīng)該很熟悉 ng-model 這個指令,我們通過它來實現(xiàn)數(shù)據(jù)的雙向綁定。那么在 Angular 中有對應(yīng)的指令么 ?答案是有滴,它就是 ngModel 指令。

ngModel雙向綁定示例

import { Component } from '@angular/core';
@Component({
  selector: 'exe-app',
  template: `
   <p>你輸入的用戶名是:{{ username }}</p> 
   <input type="text" [(ngModel)]="username" />
   `
})
export class AppComponent {
  username: string = '';
}

ngModel表單驗證示例

import { Component } from '@angular/core';
@Component({
  selector: 'exe-app',
  styles:[
    `.error { border: 1px solid red;}`
  ],
  template: `
   <p>你輸入的用戶名是:{{ username }}</p>
   <input type="text" 
      [(ngModel)]="username" 
      #nameModel="ngModel" 
      [ngClass]="{error: nameModel.invalid}"
      required/>
   {{nameModel.errors | json}}
   `
})
export class AppComponent {
  username: string = '';
}

以上示例利用 @Directive 指令 metadata 信息中的 exportAs 屬性,獲取 ngModel 實例,進行獲取控件的狀態(tài),控件狀態(tài)分類如下:

valid - 表單值有效

pristine - 表單值未改變

dirty - 表單值已改變

touched - 表單已被訪問過

untouched - 表單未被訪問過

關(guān)于Angular中Input和Output有什么用就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

標(biāo)題名稱:Angular中Input和Output有什么用-創(chuàng)新互聯(lián)
分享URL:http://bm7419.com/article40/dgooeo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站排名、網(wǎng)站導(dǎo)航、電子商務(wù)、軟件開發(fā)、Google動態(tài)網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

搜索引擎優(yōu)化