Angular4组件交互笔记
组件交互这节一共有七个子标题:
- 通过输入型绑定把数据从父组件传到子组件
- 通过setter截听输入属性值的变化
- 通过ngOnChanges()来截听输入属性值的变化
- 父组件监听子组件的事件
- 父组件与子组件通过本地变量互动
- 父组件调用@ViewChild()
- 父组件和子组件通过服务来通讯
其中最常用的是以下两个:
- 通过输入型绑定把数据从父组件传到子组件
- 父组件监听子组件的事件
对于这两个的理解
下图展示了父子组件通信的方式:
用以下代码体现上图即:
import { Component } from '@angular/core';
@Component({
selector: 'app-parent',
template: `
<app-child
[fruit]="fruit"
(onTold)="listen($event)">
</app-child>
<p>{{word}}</p>
`
})
export class ParentComponent {
fruit: string = 'apple';
word: string;
listen(news: string) {
this.word = news;
}
};
import { Component, EventEmitter, Input, Output } from '@angular/core';
@Component({
selector: 'app-child',
template: `
Parent give child an {{fruit}},
<button (click)="tell(message)">Tell Parent</button>
that I like it.
`
})
export class ChildComponent {
@Input() fruit: string;
@Output() onTold = new EventEmitter<string>();
message: string = 'I really like it!';
tell(information: string) {
this.onTold.emit(information);
}
};
-
父组件需要向子组件传送数据时
这种情况下子组件需要做的就是对某个属性(fruit)添加@Input()修饰器,表示这个属性是可以接收外部的输入的:
@Input() fruit: string;
父组件需要做的,就是将想要传递给子组件的值的属性用以下方式写在标签中等式的右边:
<app-child [fruit]="fruit"></app-child>
等式左边带中括号的fruit指的是子组件ChildComponent的输入属性fruit;
等式右边的fruit指的是父组件ParentComponent的fruit属性。
这样,数据就从父组件流向了子组件。具体来说,是父组件class中的fruit属性先传给自己模板中的fruit,然后模板中的fruit再传递给子组件的输入属性fruit。
也就是图片中:
父组件class的property→父组件的template→子组件的@Input -
子组件需要向父组件传送数据时
这种情况会比父组件向子组件传送数据复杂一些。-
子组件需要做的事情是:
-
@Output() onTold = new EventEmitter<string>();
a. 将想要传递给父组件的属性(onTold)添加@Output修饰器,表示这个属性可以对外输出。
b. new EventEmitter<string>(),从EventEmiiter的字面意思来看,是事件发射器,可以对外弹射事件(稍后会看到)。
也就是说,onTold是个对外输出的事件发射器,并且onTold携带的参数类型是string。 - 绑定事件(如点击事件)。
<button (click)="tell(message)">Tell Parent</button>
message: string = 'I really like it!';
- 在事件处理器中将onTold事件和数据弹射到外部。
因为onTold是个事件发射器,所以这里用了emit方法向外部(或者说向上)弹射事件和参数。tell(information: string) { this.onTold.emit(information); }
上述三点也就是说,子组件自身事件发生时,在事件处理器中利用onTold属性(向上弹射)事件和参数,外部可以接收到这个onTold属性。
-
-
父组件需要做的事件是:
-
<app-child (onTold)="listen($event)"></app-child>
onTold做为连接父子组件的桥梁,在子组件内部表现为属性,在外部表现为一个自定义事件。因此标签上的onTold添加了圆括号,即事件绑定。
父组件绑定监听子组件向上弹射的自定义onTold事件,并定义好事件处理器listen。listen方法中的$event接收子组件传递给父组件的参数。 listen(news: string) { this.word = news; }
也就是图片中:
子组件class的@Output→父组件的template→父组件中class的事件处理器方法 -
-
总结一下父子组件通信:
数据从父组件流向子组件:父组件class的属性→父组件的模板→子组件的@Input属性;
数据从子组件流向父组件:子组件的@Output属性→父组件的模板→父组件class的事件处理器方法。子组件自身的事件被触发时,在自身事件处理器中向上弹射自定义事件(或者说向上触发自定义事件),父组件通过监听这个自定义事件接收数据。
以上是我对父子组件通信方式的理解。
图片引用自知乎: https://zhuanlan.zhihu.com/p/29610405
除了Angular官网,额外参考的文档也是上面这个网址,文章写得很好,建议阅读。