angular组件之间通信的机制

1 输入性属性: 通常带着@Input装饰器

2 通过setter截听属性值的变化。使用一个输入属性的setter, 以拦截父组建中值的变化,并采取行动;

eg: export ChildComponent {

  private _name = '';

  @Input()  set name( name: string) { this._name = (name && name.trim()) || '< no name set >'

 

  get name() : string { return this._name};

 

}

@Component ({

  template: `

<h2>Master controls {{names.length}} names</h2>

<app-name-child *ngFor="let name of names" [name]="name"></app-name-child>`

})

 

3 ngOnChanges() 来截听输入属性值的变化。

 

父组件监听子组件的事件。 

子组件暴露一个EventEmitter属性,当事件发生时,子组件利用该属性emits(向上弹射)事件。通常带有@Output装饰器,

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;
}
}

#------------------父组件接收子组件的方法------------#

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++;
}
}

 

父组件与子组件通过本地变量互动, 父组件不能使用数据绑定来读取子组件的属性。 把本地变量(#var) 放到子组件的tag中,用来代表子组件。

这样父组件的模板就得到了子组件的引用,于是可以在父组件的模板中访问

 

父组件调用@viewChild() 。这个本地变量方法是简单便利的方法,但是父组件-子组件的连接必须全部在父组件的模板中进行,父组件本身的代码对子组件没有访问权限。

如果父组件的类需要读取子组件的属性或调用子组件的方法,就不能使用本地变量方法。当父组件类需要这种访问时,可以把子组件作为ViewChild, 注入到父组件中。

import { AfterViewInit, ViewChild } from '@angular/core';
import { Component } from '@angular/core';
import { CountdownTimerComponent } from './countdown-timer.component';

@Component({
selector: 'app-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>
<app-countdown-timer></app-countdown-timer>
`,
styleUrls: ['../assets/demo.css']
})
export class CountdownViewChildParentComponent implements AfterViewInit {

@ViewChild(CountdownTimerComponent, {static: false})
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(); }
}

 

父组件和子组件通过服务来通讯。

父组件和子组件共享同一个服务,利用该服务在组件家族内部实现双向通讯。 该服务的作用域被限制在父组件和其子组件之内,这个组件子树之外的组件将无法访问该服务或与他们通信。

eg:

import { Injectable } from '@angular/coore';

import { Subject} from 'rxjs';  // Subject(主体) 相当于EventEmitter,并且是将值或事件多路推送给多个Observer的唯一方式。

@Injectable()

export class MissionService {

// Observable string source

private mission AnnouncedSource = new Subject<string>();

private missionConfirmedSource = new Subject<string>();

 

//Observable string streams

missionAnnouced$ = this.missionAnnouncedSource;asObservable();

missionConfirmed$ = this.missionCOnfirmedSource.asObservable();

 

// Service message commands

announceMission(mission: String) { this.missionAnnounceSource.next(mission);}

confirmMission(astronaur: String) {this.missionConfirmedSource.next(astronaur);}

}

 

其中子组件: missionService.missionAnnoiced$.subscribe(res => {})

 

posted @ 2019-06-18 15:53  xiaogao2700c  阅读(222)  评论(0编辑  收藏  举报