angular组件之间通信的机制

mac2022-06-30  86

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

最新回复(0)