1. 我们知道,在 Angular 框架中,可以用 @Input 和 @Output 来进行父子组建的传参, 不是很复杂,可以参考官网: Angular
2. 同级组件传参可以用 Observable , 让我们看一下它在 Angular 官网中的的定义:
Observable3. 我们先实现如下功能:
set,get4. 新建一个Angular项目, 并新建两个组件和一个service,如:
set组件 get组件 作为传递数据用的service5. 清空 app.component.html, 并把两个组件放在里面,如:
app.component.html6. 编写 setData 组件和 getData 组件 还有 context.service, 代码如下:
setData.component.html:
<div>
<input type="text" [(ngModel)]="setValue" (blur)="onBlur()">
</div>
setData.component.ts:
import { Component, OnInit } from '@angular/core';
import { ContextService } from '../context.service';
@Component({
selector: 'app-set-data',
templateUrl: './set-data.component.html',
styleUrls: ['./set-data.component.scss']
})
export class SetDataComponent implements OnInit {
public setValue: string;
constructor( private contextService: ContextService) { }
ngOnInit() {}
public onBlur() {
this.contextService.setData(this.setValue);
}
}
getData.component.html:
<div>
<input type="text" [(ngModel)]="getValue" (focus)="onFocus()">
</div>
getData.component.ts:
import { Component, OnInit } from '@angular/core';
import { ContextService } from '../context.service';
@Component({
selector: 'app-get-data',
templateUrl: './get-data.component.html',
styleUrls: ['./get-data.component.scss']
})
export class GetDataComponent implements OnInit {
public getValue: string;
constructor(private contextService: ContextService) { }
ngOnInit() {}
public onFocus() {
this.contextService.getData().subscribe((e: string) => {
this.getValue = e;
});
}
}
context.service:
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class ContextService {
private value: string;
constructor() { }
public setData(setValue: string) {
this.value = setValue;
}
public getData() {
return new Observable((obs) => {
obs.next(this.value);
});
}
}
!!! 别忘记在app.module.ts中引入FormsModule,因为使用input, 要不然会报错
7. 这样虽然满足了上述要求,但是现在我要求改变了,我需要在 setData 组件输入的同时,getData 组件要和它一起变化,那要怎么做呢,这样可以使用 RXJS 库 中的 Subject 操作符,那为什么不继续使用 Observable 了呢,其实 Subject 是对 Observable 的一种封装,因为 observable 只能进行单播(unicast), 也就是说它一次只能广播一个对象,如果要通知第二个对象,就需要新 New 一个 Observable,这样很不理想,也很浪费性能,而 Subject 不仅使用起来代码简洁,而且是多播的(muticast), 像我们新改的这个要求,如果使用 Observable 就会报错,而使用Subject就完全不会出现问题。
8. 最终结果如下:
Subject9. 因为实在懒得截图(·O·),所以我上传到了 giuhub上:GitHub - daozun/test_Observable: Observable 和 Subject 练习 大家有兴趣可以去看看。
10. 这样每个组件都相互传递状态或值,这样管理起来很麻烦,小一点的项目还好,如果有好几百个组件他们都要相互传参的话,那不仅编写起来很复杂,维护的话更是地狱,我们需要把这些状态放在一个专门的文件夹下,并且制定一些规则,把这些状态的权限设置为最高,比作一颗树的话,那么他们就在树顶,并规定数据流只能自上而下,不能从下向上传递,所幸的是有专门的类库帮我们实现了,这里推荐: NgRx Docs,如果有使用过 Vuex 或者 Redux 这些状态管理库的话,那么可以很快上手 NgRx,它也有像 Action、Dispatch、Store 这些东西。
11.因个人水平有限,如文章中有错误的地方,欢迎评论指正,谢谢!!!
网友评论