• 使用 RXJS Subject 轻松解决非父子组件传值问题


    Angular 介绍了父组件给子组件传值的方法:

    1. 通过输入型绑定把数据从父组件传到子组件

    子组件使用 @Input 装饰器接受父组件的数据。

    1. 父组件与子组件通过本地变量互动

    父组件不能使用数据绑定来读取子组件的属性或调用子组件的方法。但可以在父组件模板里,新建一个本地变量来代表子组件,然后利用这个变量来读取子组件的属性和调用子组件的方法

    另有通过 setter 截听输入属性值的变化,和 ngOnChanges() 来截听输入属性值的变化等方式。

    也介绍了子组件给父组件传值的方法:

    1. 父组件监听子组件的事件

    子组件暴露一个 EventEmitter 属性,当事件发生时,子组件利用该属性 emits (向上弹射)事件。父组件绑定到这个事件属性,并在事件发生时作出回应。

    1. 父组件调用@ViewChild()

    可以把子组件作为 ViewChild,注入到父组件里面。

    也介绍了父组件和子组件通过服务来通讯。

    受此启发,没有父子关系的两个组件之间可以也可以通过服务来通讯。

    思路是:

    1. 新建一个服务,实例化一个 Subject 对象 Subject
    2. 在该服务类中,设置输入属性 get,返回 Subject 对象的 Observable
    3. 在该服务类中,设置输出属性 set,将接收到的值通过 Observable 对象的 next 方法发送出去。
    4. 需要传递值的组件中,调用 set 方法。
    5. 需要接收值的组件中,调用 get 方法获取到值。

    具体的业务如下:

    • 现有父组件 QaComponent,子组件 ListComponent(问答列表),子组件 RecommendProblemComponent(推荐问题)。
    • 点击推荐问题的问题项,该项作为问题,在问答列表组件中调用接口获取答案展示。

    按照以前的思路现将 RecommendProblemComponent 的问题 emits 发射给父组件,父组件接收到后使用 @Input() 属性绑定到 ListComponent,两步,不利于扩展和维护。

    现在使用服务通讯的方法,一步完成。使用 Angular 核心代码如下:

    1. 新建一个服务 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);  // 请求接口,获取答案
    });
    
  • 相关阅读:
    为什么图层1剪切蒙版到图层2,图层1不见了?
    制作放射状背景
    如何制作底纹(2)
    如何制作底纹?
    web网页按钮如何制作
    取得表中数据的insert语句
    Solr查询详解
    .NET开发过程中的全文索引使用技巧之Solr
    工作中常用的数据库操作脚本整理
    如何在Linux上编译c++文件
  • 原文地址:https://www.cnblogs.com/xinjie-just/p/12228661.html
Copyright © 2020-2023  润新知