为什么要在共享服务中使用Subject或BehaviorSubject,如果无法观察,就无法实现相同的目标?

时间:2019-03-04 05:58:56

标签: angular

为了在各个组件之间共享数据,我们将共享服务与主题或BrhaviorSubject结合使用,如下所示,

import { Injectable } from '@angular/core';
import { Observable, Subject } from 'rxjs';

@Injectable()
export class DataService {
    private subject = new Subject<any>();

    // Method to set navmenu //
    public sendData(data: boolean) {
        this.subject.next(data);
    }

    // Method to clear navmenu //
    public clearData() {
        this.subject.next();
    }

    // Method to get navmenu //
    public getData(): Observable<any> {
        return this.subject.asObservable();
    }
}

但是我们可以不用观察到Subject或BehaviorSubject就可以达到相同的效果。 在下面的示例中,组件A和B都共享EmailService的实例,因此,如果组件A更改了值(emailService.apiKey),则组件B中的值相同,反之亦然,如下所示,

class EmailService{
  public apiKey: string = 'ABCD1234';
}

@Component({
  selector: 'component-a',
  template: `
  Component A - {{emailService.apiKey}}
  <button (click)="changeApiKey()">Change Key</button>
  `
})

export class A{
  public emailService: EmailService;
  constructor(emailService: EmailService){
    this.emailService = emailService;
  }

  changeApiKey(){
    this.emailService.apiKey = "XYZ1234";
  }
}

@Component({
  selector: 'component-b',
  template: `
  Component B - {{emailService.apiKey}}
  <button (click)="changeApiKey()">Change Key</button>
  `
})

export class B{
  public emailService: EmailService;
  constructor(emailService: EmailService){
    this.emailService = emailService;
  }

  changeApiKey(){
    this.emailService.apiKey = "ABCD1234";
  }
}

@Component({
  selector: 'app-root',
  template: `

    <component-a></component-a>
    <br />
    <component-b></component-b>
  `,
  providers: [
    EmailService
  ]
})

export class AppComponent {

}

Can someone please explain why most of the examples and tutorials use observable in shared service. What's the advantage in using that ??

2 个答案:

答案 0 :(得分:1)

您很少有理由要使用它们。总体而言,您可以通过以下方式告知组件

  • 承诺
  • 事件
  • 可观察

让我们简要介绍一下所有内容:

  • 您可以使用promise,但是它有一个缺点,您只能将事件通知components一次。一个诺言只能被解决,然后一次消失。可以说,您要将产品添加到购物车,不能使用promise,因为它会多次发生。

  • 您可以使用事件,类似于$broadcast中的$emitangularJS

  • 您拥有observables,它也是一种事件,但是RxJ附带了许多其他功能。您可以使用switchMap()mergeMap()等等。这就像简单事件中事件的演变版本。

答案 1 :(得分:0)

SubjectBehaviourSubject在以下情况下很有用:component 2要根据来自component 1的数据更改采取措施,反之亦然

如果您没有使用publish/subscribeSubject之类的BehaviorSubject模式,那么很难观察到数据变化并执行操作。