Angular4學習筆記——組件之間的交互

經過輸入型綁定把數據從父組件傳到子組件

Angular對於父組件 => 子組件的數據通訊作法和Vue很類似。html

// 父組件html模板
<app-hero-child *ngFor="let hero of heroes"
      [hero]="hero"
      [master]="master">
    </app-hero-child>
// 子組件接收數據
import { Component, Input } from '@angular/core';
import { Hero } from './hero';

export class HeroChildComponent {
  @Input() hero: Hero;
  @Input('master') masterName: string;
}
// 第二個@Input爲子組件的屬性名masterName指定一個別名master,可是這個作法並不推薦

看着是否是很眼熟,寫代碼的邏輯和Vue幾乎能夠說是同樣了,只是寫法上略有區別而已。 前端

這個問題下還有兩個截聽輸入屬性值變化的方法,代碼邏輯不難推,可是其中的應用場景方面我還沒想到是怎麼樣的,以後也許繼續看Angular文檔會理解的更透徹一些,屆時再來補充啦~~app

父組件監聽子組件的事件

這個操做方法也和Vue中的作法很是接近,並且在上一篇筆記中也有所說起。
具體思路:子組件暴露一個EventEmitter屬性,當事件發生時,子組件利用該屬性emits(向上彈射)事件。父組件綁定到這個事件屬性,並在事件發生時做出迴應。
還有,子組件的EventEmitter屬性是一個輸出屬性,一般帶有@Output裝飾器,比較完整的示例以下:函數

// 子組件:先在本身的組件中觸發了vote方法,而後在vote方法中向父組件發出onVoted事件,同時傳送一個payload(agreed)
// 在Vue中的寫法是this.$emit(onVoted,agreed)
import { Component, EventEmitter, Input, Output } from '@angular/core';

export class VoterComponent {
  @Input()  name: string;
  @Output() onVoted = new EventEmitter<boolean>();
  voted = false;
 
  vote(agreed: boolean) {
    this.onVoted.emit(agreed);
    this.voted = true;
  }
}
// 父組件:監聽onVoted事件,若是監聽到了則觸發本身組件中的agree方法,同時經過$event把payload傳參給agree
html:
<app-voter (onVoted)="onVoted($event)"></app-voter>
ts:
export class VoteTakerComponent {
  onVoted(agreed: boolean) {
    agreed ? this.agreed++ : this.disagreed++;
  }
}

父子組件的其餘互動關係

父組件與子組件經過本地變量互動

父組件對子組件的數據綁定屬於單向綁定,子組件沒法直接把數據、屬性和自身的方法傳送給父組件使用。儘管有EventEmitter屬性,可是有時候須要直接訪問子組件的內容,用這種方法並不合適。this

// 能夠在父組件的模板中直接訪問子組件的全部屬性和方法,例如此例即是直接訪問了子組件的start(),stop()方法和seconds屬性
<button (click)="timer.start()">Start</button>
<button (click)="timer.stop()">Stop</button>
<div class="seconds">{{timer.seconds}}</div>
<app-countdown-timer #timer></app-countdown-timer>

父組件調用@ViewChild()

上述方法有必定侷限性:父組件-子組件的鏈接必須所有在父組件的模板中進行。父組件自己的代碼對子組件沒有訪問權。若是想要在代碼中直接訪問子組件的內容,可使用這個方法把子組件做爲ViewChild,注入到父組件裏面,具體操做以下:code

// 須要經過@ViewChild屬性裝飾器,將子組件CountdownTimerComponent注入到私有屬性timerComponent裏面,並掛在AfterViewInit生命週期鉤子裏
export class CountdownViewChildParentComponent implements AfterViewInit {
// 在父組件中將子組件註冊爲變量timerComponent,記得在括號裏寫明子組件名字~~ 
  @ViewChild(CountdownTimerComponent)  private timerComponent: CountdownTimerComponent;
// 這樣就能夠經過this.timerComponent訪問子組件的內容了
  start() { this.timerComponent.start(); }
  stop() { this.timerComponent.stop(); }
}

經過服務來通信

父組件和它的子組件(們)共享同一個服務,利用該服務在父子組件之間實現雙向通信。
該服務實例的做用域被限制在父組件和其子組件(們)內。這個組件子樹以外的組件將沒法訪問該服務或者與它們通信。htm

父子組件經過各自的構造函數注入該服務。文檔中的例子還須要一些額外知識才能明白,以後再分析啦!~生命週期

前端新人,寫的不對的地方還請指出;
若是以爲對你有幫助,能夠點個贊鼓勵一下我哦!~~事件

相關文章
相關標籤/搜索