使用主题和代理传递数据

时间:2018-03-20 15:13:05

标签: angular rxjs

是否可以使用服务中的主题进行双向数据流?例如,假设我想要一些组件检索信息,然后通过服务Subject发布它以供其他其他组件使用。

消费组件然后对此信息进行一些更改,然后重新发布,以便原始组件可以检索更改。

使用Observer模式可以实现吗?

另外,如果我想观察这些数据是否有变化(假设数据是通过数组传入的),我是否必须使用proxy来完成此操作?

2 个答案:

答案 0 :(得分:2)

在组件之间传递数据时,我发现RxJS BehaviorSubject非常有用。

您还可以使用常规RxJS Subject通过服务共享数据,但这就是我更喜欢BehaviorSubject的原因。

  1. 它将始终返回订阅时的当前值 - 无需调用onNext()。
  2. 它有一个getValue()函数来提取最后一个值作为原始数据。
  3. 确保组件始终接收最新数据。
  4. 您可以使用asObservable()从行为主题中获得观察结果      关于行为主体的方法。
  5. Refer this for more
  6. 示例

    在服务中,我们将创建一个私有的BehaviorSubject,它将保存消息的当前值。我们定义一个currentMessage变量来处理这个数据流作为一个可供其他组件使用的observable。最后,我们创建了在BehaviorSubject上调用next的函数来更改其值。

    父,子和兄弟组件都接受相同的治疗。我们在组件中注入DataService,然后订阅currentMessage observable并将其值设置为等于消息变量。

    现在,如果我们在任何一个组件中创建一个更改消息值的函数。更新后的值会自动广播到所有其他组件。

    <强> shared.service.ts

    import { Injectable } from '@angular/core';
    import { BehaviorSubject } from 'rxjs/BehaviorSubject';
    
    @Injectable()
    export class SharedService {
    
      private messageSource = new BehaviorSubject<string>("default message");
      currentMessage = this.messageSource.asObservable();
    
      constructor() { }
    
      changeMessage(message: string) {
        this.messageSource.next(message)
      }
    
    }
    

    <强> parent.component.ts

    import { Component, OnInit } from '@angular/core';
    import { DataService } from "../data.service";
    
    @Component({
      selector: 'app-parent',
      template: `
         {{message}}
       `,
       styleUrls: ['./parent.component.css']
    })
    export class ParentComponent implements OnInit {
    
      message: string;
    
      constructor(private data: DataService) { }
    
      ngOnInit() {
        this.data.currentMessage.subscribe(message => this.message = message)
      }
    }
    

    <强> sibling.component.ts

    import { Component, OnInit } from '@angular/core';
    import { SharedService } from "../shared.service";
    
    @Component({
      selector: 'app-sibling',
      template: `
        {{message}}
        <button (click)="newMessage()">New Message</button>
      `,
      styleUrls: ['./sibling.component.css']
    })
    export class SiblingComponent implements OnInit {
    
      message: string;
    
      constructor(private service: SharedService) { }
    
      ngOnInit() {
      }
    
      newMessage() {
        this.service.changeMessage("Hello from Sibling");
      }
    
    }
    

答案 1 :(得分:1)

完全有可能:

  1. 找出您需要的主题类型,正常主题,行为主题或重播主题。每个都有自己的用例,我建议您查看这个问题,以获得清晰简洁的解释:Angular 2 special Observables (Subject / Behaviour subject / ReplaySubject)

  2. 在服务中声明您的主题。

  3. 在主要组件中调用next()值,您的第二个组件将听取该值。

  4. 然后,您可以从辅助组件订阅该主题并进行修改。

  5. 从此处,您可以使用修改后的数据调用同一主题的next()值,也可以在服务中创建单独的主题,并使用该主题将修改后的数据传入。无论哪种情况,您都可以在主要组件中订阅以获取该数据。我建议使用后面的选项,因为我假设您修改了数据,您将更改对象并严格键入主题以捕获错误。

  6. 希望这会有所帮助。