一、@Input与@Output (类似于Vue中的Prop和$emit自定义事件)
-
父组件向子组件传递信息。父组件通过模板属性传递,子组件通过@Input接收属性
Child.ts:
Child.html:
Father.html:
Father.ts
-
用于子组件向父组件传递信息,类似于vue中的this.$emit()自定义事件;通常搭配@Output装饰器使用。
子组件 child.ts 自定义open和close事件:
import { Component, Input,Output,EventEmitter } from ‘@angular/core’;
父组件 father.ts:
二、@Input输入属性还可以通过setter拦截属性值的变化。
name-child.component.ts
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-name-child',
template: '<h3>"{{name}}"</h3>'
})
export class NameChildComponent {
private _name = '';
//@Input接收父组件通过模板属性传过来的name,在set()里面进行了拦截处理(会trim 掉名字里的空格,并把空值替换成默认字符串)然后渲染模板的时候会触发getter取值。
@Input()
set name(name: string) {
this._name = (name && name.trim()) || '<no name set>';
}
get name(): string { return this._name; }
}
name-parent.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-name-parent',
template: `
<h2>Master controls {{names.length}} names</h2>
<app-name-child *ngFor="let name of names" [name]="name"></app-name-child>
`
})
export class NameParentComponent {
// Displays 'Dr IQ', '<no name set>', 'Bombasto'
names = ['Dr IQ', ' ', ' Bombasto '];
}
三、通过ngOnChanges()生命周期来截听输入属性值@Input的变化
本地变量#name和@ViewChild的区别是:设置本地变量的时候,只能在父组件的模板中访问子组件的属性和方法;设置@ViewChild的时候,只能在父组件的类中访问子组件的属性和方法。
四、父组件模板中给子组件定义本地变量#name,就可以在父组中件的模板中访问子组件的所有属性和方法。
child.ts
import { Component, OnDestroy, OnInit } from '@angular/core';
@Component({
selector: 'child',
template: '<p>{{message}}</p>'
})
export class CountdownTimerComponent implements OnInit, OnDestroy {
message = '';
seconds = 11;
start() { this.countDown(); }
stop() {
this.clearTimer();
this.message = `Holding at seconds`;
}
}
father.ts
import { Component } from '@angular/core';
import { child} from './child';
@Component({
selector: 'father',
template: `
<button (click)="timer.start()">Start</button>
<button (click)="timer.stop()">Stop</button>
<div>{{timer.message }}</div>
<child #timer></child>
`,
styleUrls: ['../assets/demo.css']
})
export class CountdownLocalVarParentComponent { }
五、父组件的类通过调用@ViewChild(子组件)来读取子组件的属性和调用它的方法;结合生命周期钩子 AfterViewInit(当 Angular 初始化完组件视图及其子视图或包含该指令的视图之后调用。)的引用
father.ts
import { AfterViewInit, ViewChild } from '@angular/core';
import { Component } from '@angular/core';
import { child} from './child';
@Component({
selector: 'father',
template: `
<button (click)="start()">Start</button>
<button (click)="stop()">Stop</button>
<div>{{ message() }}</div>
<child></child>
`,
styleUrls: ['../assets/demo.css']
})
export class CountdownViewChildParentComponent implements AfterViewInit {
@ViewChild(child)
private timerComponent: child;
message() { 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.message= () => this.timerComponent.message, 0);
}
start() { this.timerComponent.start(); }
stop() { this.timerComponent.stop(); }
}