Passing Data with Subjects and Proxies

前端 未结 2 1307
猫巷女王i
猫巷女王i 2020-11-27 23:46

Is it possible to have a 2 way data flow using Subjects in a service? Suppose for example that I want some component to retrieve information and then post it through the ser

2条回答
  •  无人及你
    2020-11-28 00:35

    When passing data between components, I find the RxJS BehaviorSubject very useful.

    You can also use a regular RxJS Subject for sharing data via a service, but here’s why I prefer a BehaviorSubject.

    1. It will always return the current value on subscription - there is no need to call onNext().
    2. It has a getValue() function to extract the last value as raw data.
    3. It ensures that the component always receives the most recent data.
    4. you can get an observable from behavior subject using the asObservable() method on behavior subject.
    5. Refer this for more

    Example

    In a service, we will create a private BehaviorSubject that will hold the current value of the message. We define a currentMessage variable to handle this data stream as an observable that will be used by other components. Lastly, we create the function that calls next on the BehaviorSubject to change its value.

    The parent, child, and sibling components all receive the same treatment. We inject the DataService in the components, then subscribe to the currentMessage observable and set its value equal to the message variable.

    Now if we create a function in any one of these components that changes the value of the message. The updated value is automatically broadcasted to all other components.

    shared.service.ts

    import { Injectable } from '@angular/core';
    import { BehaviorSubject } from 'rxjs';
    
    @Injectable()
    export class SharedService {
    
      private messageSource = new BehaviorSubject("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}}
        
      `,
      styleUrls: ['./sibling.component.css']
    })
    export class SiblingComponent implements OnInit {
    
      message: string;
    
      constructor(private service: SharedService) { }
    
      ngOnInit() {
      }
    
      newMessage() {
        this.service.changeMessage("Hello from Sibling");
      }
    
    }
    

提交回复
热议问题