本文是自己的学习笔记,主要参考资料如下。
- B站《2020最新Angular实战教程》,老陈打码制作,https://www.bilibili.com/video/BV1i741157Fj?p=2。
这里写目录标题
1、组件通信简述
组件之间的通信简单来说就是A组件中的一个变量传递给B组件。而组件之间的通信只限于父子组件之中
1.1、什么是父子页面
我们创建一个新页面child.component.ts
。
然后我们在主页面中直接引用这个`````
那么app.component
和child.component
就是父子页面,前者是父页面,后者是子页面。
1.2、父页面向子页面传值
首先,在父页面中定义一个变量sendChildMsg
。之后要将这个变量传递给子页面
1.2.2、子页面中定义接收器
先在子页面的ts中声明Input
。
之后使用@Input
定义接收器。
1.2.3、父页面传值给接收器
在父页面的html中,将变量值传递给子页面的某一个接收器。中括号中是接收器名称,后面指定的是父页面中的变量。
我们在子页面中的html中直接把接收器当成普通变量使用,可以正常显示。
1.2.3.1、传值的多种写法
这里有个小插曲,[input]="sendChildMsg"
是表示将sendChildMsg
这个变量传递给子页面的接收器,不是将字符串sendChildMsg
赋值给input
。如果是想传常量而不是变量的话,有下面两种写法,不加中括号或者加上单引号。
input="sendChildMsg"
[input]="'sendChildMsg'"
1.3、子页面向父页面传值
1.3.1、子页面定义发送器
先引入Output和EventEmitter
。
之后定义发送器,这里发送器的类型是EventEmitter
,不能像父页面传值给子页面那样接收器类型为一般字符串。
定义发送器的逻辑,这里为了方便,我将发送器的逻辑定义在一个button的click事件中。由点击事件触发传值。
onClick() {
this.childEmitter.emit({msg:"send to father view"});
}
1.3.2、父页面中定义接收逻辑
父页面中定义一个方法接收子页面的传值,方法参数为事件类型即可。
getChildMsg($event) {
alert(event.msg);
}
1.3.3、绑定子页面发送器和父页面接收方法
<app-child [input]="sendChildMsg" (childEmitter)="getChildMsg($event)"></app-child>
在父页面的html中绑定发送器和接收方法。其中,(childEmitter)
是子页面发送器的名称,"getChildMsg($event)"
是父页面的接收方法名。
现在我们点击按钮,消息传递成功。
1.4、信息双向绑定
以上的两种通信方式,变量的传递都是单向的。比如父页面向将变量a赋值给子页面的接收器input,a变化时input也会实时变化,但input变化时a不会跟着改变。
Angular中提供了一种方式能让变量的双向传递,使子页面的接收器可以接受数据同时反向赋值给父页面。
1.4.1、双向绑定的实现
继续使用上面的代码样例。子页面中已定义接收器@Input() input;
,我们只要再定义一个发送器,使发送器的名字是接收器名+Change
即可。在这次的例子中发送器名是inputChange
,这样就完成双向绑定的定义。代码如下。
export class ChildComponent {
@Input() input;
@Output() inputChange = new EventEmitter();
constructor() { }
ngOnChanges() {
this.inputChange.emit("emit");
}
}
ngOnChanges
函数在ChildComponent初始化时就会执行一次,所以父页面将变量a传给input后,input随即就会将变量a的值赋成"emit"
。
之后父页面的html代码改成下面的内容
<app-child [(input)]="sendChildMsg"></app-child>
<button (click)="onClick()">button</button>
[(input)]
表示既是发送器也是接收器。我们另外定义一个按钮,用这个按钮来查看sendChildMsg
这个变量的值有没有发生变化。
下面是父页面的ts代码。
export class AppComponent {
sendChildMsg = "sendChildMsg";
onClick() {
console.log(this.sendChildMsg);
}
}
我们在页面上点击button,发现sendChildMsg的值确实被改成了"emit",双向绑定成功。
1.5、发布-订阅
发布订阅模式可以不受父子关系的约束,实现组件的通信。
和通常的发布订阅模式一样,整个过程无非就是这三个,创建Topic,向Topic发送信息,订阅Topic。
1.5.1、代码
一般来说是放在service
里创建topic。
首先创建一个servcie
ng g /service/message
在servcie中声明一个Subject
变量,它就是Topic。然后使用它的next()
方法定义发送消息的方法。
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/internal/Subject';
@Injectable({
providedIn: 'root'
})
export class MessageService {
private msg = new Subject<String>();
public sendMsg(message: String) {
this.msg.next(message);
}
public getMsg() {
return this.msg;
}
}
订阅消息,要注意,订阅消息的语句要放在ngOnInit()
的第一行执行,不然可能会订阅失败。
ngOnInit() {
this.messageService.getMsg.subcribe(data =>{
// businessCode
})
}
发布消息
this.messageService.sendMsg('hello world');