Angular
介绍了父组件给子组件传值的方法:
子组件使用
@Input
装饰器接受父组件的数据。
父组件不能使用数据绑定来读取子组件的属性或调用子组件的方法。但可以在父组件模板里,新建一个本地变量来代表子组件,然后利用这个变量来读取子组件的属性和调用子组件的方法
另有通过 setter
截听输入属性值的变化,和 ngOnChanges()
来截听输入属性值的变化等方式。
也介绍了子组件给父组件传值的方法:
子组件暴露一个
EventEmitter
属性,当事件发生时,子组件利用该属性emits
(向上弹射)事件。父组件绑定到这个事件属性,并在事件发生时作出回应。
可以把子组件作为
ViewChild
,注入到父组件里面。
也介绍了父组件和子组件通过服务来通讯。
受此启发,没有父子关系的两个组件之间可以也可以通过服务来通讯。
思路是:
- 新建一个服务,实例化一个
Subject
对象Subject
。 - 在该服务类中,设置输入属性
get
,返回Subject
对象的Observable
。 - 在该服务类中,设置输出属性
set
,将接收到的值通过Observable
对象的next
方法发送出去。 - 需要传递值的组件中,调用
set
方法。 - 需要接收值的组件中,调用
get
方法获取到值。
具体的业务如下:
- 现有父组件
QaComponent
,子组件ListComponent
(问答列表),子组件RecommendProblemComponent
(推荐问题)。 - 点击推荐问题的问题项,该项作为问题,在问答列表组件中调用接口获取答案展示。
按照以前的思路现将 RecommendProblemComponent
的问题 emits
发射给父组件,父组件接收到后使用 @Input()
属性绑定到 ListComponent
,两步,不利于扩展和维护。
现在使用服务通讯的方法,一步完成。使用 Angular
核心代码如下:
- 新建一个服务
QaService
,设置输入输出属性,设置和发送值。
QaService
private s = new Subject<any>();
/**
* 推荐问题组件中的问题传递
* @param question: string
*/
setQuestion(question: string) {
this.s.next(question);
}
getQuestion(): Observable<string> {
return this.s.asObservable();
}
RecommendProblemComponent
发送问题:
<section class="recommend-container">
<h3>推荐问题</h3>
<ul>
<li *ngFor="let item of data" (click)="selectQuestion(item)" title="{{ item }}">{{ item }}</li>
</ul>
</section>
/**
* @param question: string
* @description 选择问题,用于提问的备用问题
*/
selectQuestion(question: string): void {
this.qaService.setQuestion(question);
}
ListComponent
接收问题:
// 接收推荐问题作为问题,重新请求
this.qaService.getQuestion().subscribe((res: string) => {
const param: QARequestParams = {
question: res
};
this.getQuestion(param); // 请求接口,获取答案
});