通过输入型绑定把数据从父组件传到子组件
hero-child.component.ts
import { Component, Input } from '@angular/core';
import { Hero } from './hero';
@Component({
selector: 'app-hero-child',
template: `
<h3>{{hero.name}} says:</h3>
<p>I, {{hero.name}}, am at your service, {{masterName}}.</p>
`
})
export class HeroChildComponent {
@Input() hero: Hero;
@Input('master') masterName: string;
}
hero-parent.component.ts
import { Component } from '@angular/core';
import { HEROES } from './hero';
@Component({
selector: 'app-hero-parent',
template: `
<h2>{{master}} controls {{heroes.length}} heroes</h2>
<app-hero-child *ngFor="let hero of heroes"
[hero]="hero"
[master]="master">
</app-hero-child>
`
})
export class HeroParentComponent {
heroes = HEROES;
master = 'Master';
}
语法要点:
在父组件中声明如:
<app-child [childAttr]=“parentAttr”> </ app-child>
在子组件中就可以导入用@Input导入childAttr:
@Input() childAttr: any;
还可以为其指定别名(但不推荐)
@Input(‘childAttrName’) childAttr: any;
通过setter截听输入属性的变化
在子组件中声明
@Input()
set name(name: string) {
this._name = (name && name.trim()) || '<no name set>';
}
通过set()能够设置从父组件传入的属性。
父组件监听子组件的属性
子组件暴露一个 EventEmitter 属性,当事件发生时,子组件利用该属性 emits(向上弹射)事件。父组件绑定到这个事件属性,并在事件发生时作出回应。
父组件
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 = ['Mr. IQ', 'Ms. Universe', 'Bombasto'];
onVoted(agreed: boolean) {
agreed ? this.agreed++ : this.disagreed++;
}
}
父组件绑定了一个事件处理器(onVoted)来响应子组件的voted方法。
子组件
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);
console.log(agreed);
this.didVote = true;
}
}
子组件的 EventEmitter 属性是一个输出属性。弹射事件给父组件。
语法要点:在父组件的模板中声明: (childEvent) = “parentEvent($event)” ,子组件的childEvent事件就可以弹射事件给父组件的parentEvent事件。
父组件与子组件通过本地变量互动
若父组件想调用子组件的属性和方法,可以在子组件标签中用#声明子组件的本地变量(如#time),就可以直接使用本地变量去获取子组件的属性和方法了。
<app-child #time></app-child>
<p>time.attr</ p>
<p>time.func()</p>
但是这个方法有局限,只能在父组件模板中获取子组件的属性和方法,父组件类不能读取到子组件类的代码。
父组件调用@ViewChild()
通过在父组件中声明
@ViewChild(ChildComponent)
private childComponent: ChildComponent;
就可以直接通过childComponent调用子组件的方法和属性。
使用@ViewChild需要挂上ngAfterViewInit()的钩子,通过该钩子把子组件ChildComponent注入到私有属性childComponent里面。