组件交互:
通过输入型绑定把数据从父组件传到子组件。
子组件
- export class HeroChildComponent {
- @Input() hero: Hero;
- @Input('master') masterName: string;
- }
- import { Component } from '@angular/core';
- import { HEROES } from './hero';
- @Component({
- selector: 'hero-parent',
- template: `
- <h2>{{master}} controls {{heroes.length}} heroes</h2>
- <hero-child *ngFor="let hero of heroes"
- [hero]="hero"
- [master]="master">
- </hero-child>
- `
- })
- export class HeroParentComponent {
- heroes = HEROES;
- master = 'Master';
- }
通过setter截听输入属性值的变化
父组件监听子组件的事件
子组件使用@output()装饰器使用emit传送带参数事件- import { Component, EventEmitter, Input, Output } from '@angular/core';
- @Component({
- selector: 'my-voter',
- template: `
- <h4>{{name}}</h4>
- <button (click)="vote(true)" [disabled]="voted">Agree</button>
- <button (click)="vote(false)" [disabled]="voted">Disagree</button>
- `
- })
- export class VoterComponent {
- @Input() name: string;
- @Output() onVoted = new EventEmitter<boolean>();
- voted = false;
- vote(agreed: boolean) {
- this.onVoted.emit(agreed);
- this.voted = true;
- }
- }
VoteTakerComponent
绑定了一个事件处理器(
onVoted()
),用来响应子组件的事件(
$event
)并更新一个计数器。
- import { Component } from '@angular/core';
- @Component({
- selector: 'vote-taker',
- template: `
- <h2>Should mankind colonize the Universe?</h2>
- <h3>Agree: {{agreed}}, Disagree: {{disagreed}}</h3>
- <my-voter *ngFor="let voter of voters"
- [name]="voter"
- (onVoted)="onVoted($event)">
- </my-voter>
- `
- })
- export class VoteTakerComponent {
- agreed = 0;
- disagreed = 0;
- voters = ['Mr. IQ', 'Ms. Universe', 'Bombasto'];
- onVoted(agreed: boolean) {
- agreed ? this.agreed++ : this.disagreed++;
- }
- }
父组件与子组件通过本地变量互动
既在子组件标签中加#xxx,xxx.即可调用子组件属性与方法非常便利,但是只能在父组件模板中使用
父组件调用@ViewChild()
首先,你要使用ViewChild
装饰器导入这个引用,并挂上AfterViewInit
生命周期钩子。
接着,通过@ViewChild
属性装饰器,将子组件CountdownTimerComponent
注入到私有属性timerComponent
里面。
组件元数据里就不再需要#timer
本地变量了。而是把按钮绑定到父组件自己的start
和stop
方法,使用父组件的seconds
方法的插值表达式来展示秒数变化。
- import { AfterViewInit, ViewChild } from '@angular/core';
- import { Component } from '@angular/core';
- import { CountdownTimerComponent } from './countdown-timer.component';
- @Component({
- selector: 'countdown-parent-vc',
- template: `
- <h3>Countdown to Liftoff (via ViewChild)</h3>
- <button (click)="start()">Start</button>
- <button (click)="stop()">Stop</button>
- <div class="seconds">{{ seconds() }}</div>
- <countdown-timer></countdown-timer>
- `,
- styleUrls: ['demo.css']
- })
- export class CountdownViewChildParentComponent implements AfterViewInit { //导入AfterViewInit钩子工具
- @ViewChild(CountdownTimerComponent) //注入子组件
- private timerComponent: CountdownTimerComponent; //声明导入的子组件名
- seconds() { return 0; }
- ngAfterViewInit() {
- // Redefine `seconds()` to get from the `CountdownTimerComponent.seconds` ...
- // but wait a tick first to avoid one-time devMode
- // unidirectional-data-flow-violation error
- setTimeout(() => this.seconds = () => this.timerComponent.seconds, 0); //定时器将子组件方法移植到父组件
- }
- start() { this.timerComponent.start(); } //将子组件方法移植到父组件
- stop() { this.timerComponent.stop(); } //将子组件方法移植到父组件
- }
父组件和子组件通过服务来通讯
1创建可注入服务,父组件中导入服务模块,注入服务,通过providers,将MissionControlComponent
提供服务的实例共享,并将其共享给它的子组件(通过
providers
元数据数组),子组件可以通过导入服务模块+构造函数将该实例注入到自身。