父元件監聽子元件的事件
阿新 • • 發佈:2020-07-29
子元件暴露一個EventEmitter
屬性,當事件發生時,子元件利用該屬性emits
(向上彈射)事件。父元件繫結到這個事件屬性,並在事件發生時作出迴應。
子元件的EventEmitter
屬性是一個輸出屬性,通常帶有@Output 裝飾器,就像在VoterComponent
中看到的。
component-interaction/src/app/voter.component.ts
import { Component, EventEmitter, Input, Output } from '@angular/core';
@Component({
selector: 'app-voter',
template: `
<h4>{{name}}</h4>
<button (click)="vote(true)" [disabled]="didVote">Agree</button>
<button (click)="vote(false)" [disabled]="didVote">Disagree</button>
`
})
export class VoterComponent {
@ Input() name: string;
@Output() voted = new EventEmitter<boolean>();
didVote = false;
vote(agreed: boolean) {
this.voted.emit(agreed);
this.didVote = true;
}
}
點選按鈕會觸發true
或false
(布林型有效載荷)的事件。
父元件VoteTakerComponent
綁定了一個事件處理器(onVoted()
),用來響應子元件的事件($event
)並更新一個計數器。
component-interaction/src/app/votetaker.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-vote-taker',
template: `
<h2>Should mankind colonize the Universe?</h2>
<h3>Agree: {{agreed}}, Disagree: {{disagreed}}</h3>
<app-voter *ngFor="let voter of voters"
[name]="voter"
(voted)="onVoted($event)">
</app-voter>
`
})
export class VoteTakerComponent {
agreed = 0;
disagreed = 0;
voters = ['Narco', 'Celeritas', 'Bombasto'];
onVoted(agreed: boolean) {
agreed ? this.agreed++ : this.disagreed++;
}
}
測試一下!
測試確保點選Agree和Disagree按鈕時,計數器被正確更新。
component-interaction/e2e/src/app.e2e-spec.ts
// ...
it('should not emit the event initially', function () {
let voteLabel = element(by.tagName('app-vote-taker'))
.element(by.tagName('h3')).getText();
expect(voteLabel).toBe('Agree: 0, Disagree: 0');
});
it('should process Agree vote', function () {
let agreeButton1 = element.all(by.tagName('app-voter')).get(0)
.all(by.tagName('button')).get(0);
agreeButton1.click().then(function() {
let voteLabel = element(by.tagName('app-vote-taker'))
.element(by.tagName('h3')).getText();
expect(voteLabel).toBe('Agree: 1, Disagree: 0');
});
});
it('should process Disagree vote', function () {
let agreeButton1 = element.all(by.tagName('app-voter')).get(1)
.all(by.tagName('button')).get(1);
agreeButton1.click().then(function() {
let voteLabel = element(by.tagName('app-vote-taker'))
.element(by.tagName('h3')).getText();
expect(voteLabel).toBe('Agree: 1, Disagree: 1');
});
});
// ...