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 => {})
转载于:https://www.cnblogs.com/xiaogao6681/p/11045613.html