标签:guid ret guide cond als 字符 方法 top 它的
子组件:
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; }
第二个@Input
为子组件的属性名masterName
指定一个别名master
(译者注:不推荐为起别名,请参见风格指南)
父组件:
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" // 子组件的 @Input() hero: Hero 对应这里的 [hero]
[master]="master" // @Input(‘master‘) masterName 对应这里的 【master】
>
</app-hero-child>
`
})
export class HeroParentComponent {
heroes = HEROES;
master = ‘Master‘;
}
使用一个输入属性的setter,以拦截父组件中值的变化,并采取行动。
子组件NameChildComponent
的输入属性name
上的这个setter,会trim掉名字里的空格,并把空值替换成默认字符串
@Input() set name(name: string) { this._name = (name && name.trim()) || ‘<no name set>‘; } get name(): string { return this._name; }
使用OnChanges
生命周期钩子接口的ngOnChanges()
方法来监测输入属性值的变化并做出回应
当需要监视多个、交互式输入属性的时候,本方法比用属性的setter更合适
子组件暴露一个EventEmitter
属性,当事件发生时,子组件利用该属性emits
(向上弹射)事件。父组件绑定到这个事件属性,并在事件发生时作出回应。
子组件的EventEmitter
属性是一个输出属性,通常带有@Output装饰器,就像在VoterComponent
中看到的
子组件:
import { Component, EventEmitter, Input, Output } from ‘@angular/core‘; @Component({ selector: ‘app-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; } }
父组件:
import { Component } from ‘@angular/core‘; @Component({ selector: ‘app-vote-taker‘, template: ` <app-voter *ngFor="let voter of voters" [name]="voter"
// onVoted 对应 子组件的@Output onVoted (onVoted)="onVoted($event)"> </app-voter> ` }) export class VoteTakerComponent { onVoted(agreed: boolean) { // agreed 就是子组件传递的参数 } }
子组件:点击按钮会触发true
或false
(布尔型有效载荷)的事件。
父组件:VoteTakerComponent
绑定了一个事件处理器(onVoted()
),用来响应子组件的事件($event
)并更新一个计数器。
父组件不能使用数据绑定来读取子组件的属性或调用子组件的方法。但可以在父组件模板里,新建一个本地变量来代表子组件,然后利用这个变量来读取子组件的属性和调用子组件的方法
子组件:
start() { } stop() { }
父组件:
template: ` <button (click)="timer.start()">Start</button> <button (click)="timer.stop()">Stop</button> <app-countdown-timer #timer></app-countdown-timer> `,
把本地变量(#timer
)放到(<countdown-timer>
)标签中,用来代表子组件。这样父组件的模板就得到了子组件的引用,于是可以在父组件的模板中访问子组件的所有属性和方法
父组件:
import { AfterViewInit, ViewChild } from ‘@angular/core‘;
import { Component } from ‘@angular/core‘;
import { CountdownTimerComponent } from ‘./countdown-timer.component‘;
@Component({
selector: ‘app-countdown-parent-vc‘,
template: `
<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)
private timerComponent: CountdownTimerComponent;
seconds() { return 0; }
ngAfterViewInit() {
setTimeout(() => this.seconds = () => this.timerComponent.seconds, 0);
}
start() { this.timerComponent.start(); }
stop() { this.timerComponent.stop(); }
}
通过@ViewChild
属性装饰器,将子组件CountdownTimerComponent
注入到私有属性timerComponent
里面
组件元数据里就不再需要#timer
本地变量了。而是把按钮绑定到父组件自己的start
和stop
方法
然后Angular会调用ngAfterViewInit
生命周期钩子,但这时候再更新父组件视图的倒计时就已经太晚了。Angular的单向数据流规则会阻止在同一个周期内更新父组件视图。我们在显示秒数之前会被迫再等一轮
(子组件CountdownTimerComponent和原来一样)
父组件和它的子组件共享同一个服务,利用该服务在家庭内部实现双向通讯。
该服务实例的作用域被限制在父组件和其子组件内。这个组件子树之外的组件将无法访问该服务或者与它们通讯。
这个MissionService
把MissionControlComponent
和多个AstronautComponent
子组件连接起来
import { Injectable } from ‘@angular/core‘; import { Subject } from ‘rxjs/Subject‘; @Injectable() export class MissionService { // Observable string sources private missionAnnouncedSource = new Subject<string>(); private missionConfirmedSource = new Subject<string>(); // Observable string streams missionAnnounced$ = this.missionAnnouncedSource.asObservable(); missionConfirmed$ = this.missionConfirmedSource.asObservable(); // Service message commands announceMission(mission: string) { this.missionAnnouncedSource.next(mission); } confirmMission(astronaut: string) { this.missionConfirmedSource.next(astronaut); } }
MissionControlComponent
提供服务的实例,并将其共享给它的子组件(通过providers
元数据数组),子组件可以通过构造函数将该实例注入到自身
父组件:MissionControlComponent
import { Component } from ‘@angular/core‘; import { MissionService } from ‘./mission.service‘; @Component({ selector: ‘app-mission-control‘, template: ` <button (click)="announce()">Announce mission</button> <app-astronaut *ngFor="let astronaut of astronauts" [astronaut]="astronaut"> </app-astronaut> <h3>History</h3> <ul> <li *ngFor="let event of history">{{event}}</li> </ul> `, providers: [MissionService] }) export class MissionControlComponent { astronauts = [‘Lovell‘, ‘Swigert‘, ‘Haise‘]; history: string[] = []; missions = [‘Fly to the moon!‘, ‘Fly to mars!‘, ‘Fly to Vegas!‘]; nextMission = 0; constructor(private missionService: MissionService) { missionService.missionConfirmed$.subscribe( astronaut => { this.history.push(`${astronaut} confirmed the mission`); }); } announce() { let mission = this.missions[this.nextMission++]; this.missionService.announceMission(mission); this.history.push(`Mission "${mission}" announced`); if (this.nextMission >= this.missions.length) { this.nextMission = 0; } } }
子组件:AstronautComponent
AstronautComponent
也通过自己的构造函数注入该服务。由于每个AstronautComponent
都是MissionControlComponent
的子组件,所以它们获取到的也是父组件的这个服务实例
mport { Component, Input, OnDestroy } from ‘@angular/core‘;
import { MissionService } from ‘./mission.service‘;
import { Subscription } from ‘rxjs/Subscription‘;
@Component({
selector: ‘app-astronaut‘,
template: `
<p>
{{astronaut}}: <strong>{{mission}}</strong>
<button
(click)="confirm()"
[disabled]="!announced || confirmed">
Confirm
</button>
</p>
`
})
export class AstronautComponent implements OnDestroy {
@Input() astronaut: string;
mission = ‘<no mission announced>‘;
confirmed = false;
announced = false;
subscription: Subscription;
constructor(private missionService: MissionService) {
this.subscription = missionService.missionAnnounced$.subscribe(
mission => {
this.mission = mission;
this.announced = true;
this.confirmed = false;
});
}
confirm() {
this.confirmed = true;
this.missionService.confirmMission(this.astronaut);
}
ngOnDestroy() {
// prevent memory leak when component destroyed
this.subscription.unsubscribe();
}
}
标签:guid ret guide cond als 字符 方法 top 它的
原文地址:http://www.cnblogs.com/vs1435/p/7792433.html