美文网首页
Angular 的同级组件传参

Angular 的同级组件传参

作者: daozun | 来源:发表于2019-11-09 18:02 被阅读0次

1. 我们知道,在 Angular 框架中,可以用 @Input 和 @Output 来进行父子组建的传参, 不是很复杂,可以参考官网: Angular

2. 同级组件传参可以用 Observable , 让我们看一下它在 Angular 官网中的的定义:

Observable

3. 我们先实现如下功能:

set,get

4. 新建一个Angular项目,  并新建两个组件和一个service,如:

set组件 get组件 作为传递数据用的service

5. 清空 app.component.html, 并把两个组件放在里面,如:

app.component.html

6. 编写 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. 最终结果如下:

Subject

9. 因为实在懒得截图(·O·),所以我上传到了 giuhub上:GitHub - daozun/test_Observable: Observable 和 Subject 练习     大家有兴趣可以去看看。

10. 这样每个组件都相互传递状态或值,这样管理起来很麻烦,小一点的项目还好,如果有好几百个组件他们都要相互传参的话,那不仅编写起来很复杂,维护的话更是地狱,我们需要把这些状态放在一个专门的文件夹下,并且制定一些规则,把这些状态的权限设置为最高,比作一颗树的话,那么他们就在树顶,并规定数据流只能自上而下,不能从下向上传递,所幸的是有专门的类库帮我们实现了,这里推荐: NgRx Docs,如果有使用过 Vuex 或者 Redux 这些状态管理库的话,那么可以很快上手 NgRx,它也有像 Action、Dispatch、Store 这些东西。

11.因个人水平有限,如文章中有错误的地方,欢迎评论指正,谢谢!!!

相关文章

网友评论

      本文标题:Angular 的同级组件传参

      本文链接:https://www.haomeiwen.com/subject/skxnbctx.html