代码之家  ›  专栏  ›  技术社区  ›  Noob

家长和孩子使用服务进行沟通?

  •  0
  • Noob  · 技术社区  · 4 年前

    我已经开始学习Angular,我从 official docs 关于使用服务的父服务通信:

    import { Injectable } from '@angular/core';
    import { Subject } from 'rxjs';
    
    @Injectable()
    export class MissionService {
    
      // Observable string sources
      private missionAnnouncedSource = new Subject<string>();
      private missionConfirmedSource = new Subject<string>();
    
      // Observable string streams
      missionAnnounced$ = this.missionAnnouncedSource.asObservable();
      missionConfirmed$ = this.missionConfirmedSource.asObservable();
    
      // Service message commands
      announceMission(mission: string) {
        this.missionAnnouncedSource.next(mission);
      }
    
      confirmMission(astronaut: string) {
        this.missionConfirmedSource.next(astronaut);
      }
    }
    

    我对这部分有点困惑:

      // Observable string streams
      missionAnnounced$ = this.missionAnnouncedSource.asObservable();
      missionConfirmed$ = this.missionConfirmedSource.asObservable();
    

    我明白 .asObservable() 以该主体为源创建一个新的可观察对象。然而,我们为什么需要它? missionAnnouncedSource 已经是可以观察到的了。 我们为什么不干脆提供这样的服务:

    import { Injectable } from '@angular/core';
    import { Subject } from 'rxjs';
    
    @Injectable()
    export class MissionService {
    
      // Observable string sources
       missionAnnouncedSource = new Subject<string>();
       missionConfirmedSource = new Subject<string>();
    
      // Service message commands
      announceMission(mission: string) {
        this.missionAnnouncedSource.next(mission);
      }
    
      confirmMission(astronaut: string) {
        this.missionConfirmedSource.next(astronaut);
      }
    }
    

    当然,我需要调整组件中的代码以使其正常工作,但我看不出有任何问题:

      //astronaut.component.ts
    
      constructor(private missionService: MissionService) {
        this.subscription = missionService.missionAnnouncedSource.subscribe(
          mission => {
            this.mission = mission;
            this.announced = true;
            this.confirmed = false;
        });
      }
    

    这是某种惯例还是我错过了什么?

    2 回复  |  直到 4 年前
        1
  •  2
  •   wlf    4 年前

    你没有 需要 但是,如果你只暴露一个可观察的物体,就不可能 next 公共变量——只能从服务内部执行。

        2
  •  1
  •   sgClaudia98    4 年前

    你的问题给了我同样的怀疑。所以我会关注它。这就是我发现的:

    从德 RxJS docs

    一个主题就像一个可观察的对象,但可以多播给许多观察者。主题就像事件发射器:它们维护着许多听众的注册。

    所以你可以做同样的事情,只是Observable不能用 next(value) 呼叫

    这 article 很好,这解释了你对 最佳实践 下面的例子就是:

    在RxJS的世界里,最好的做法是只向应用程序中会向可观察序列中添加新数据的部分公开主题。这与只允许对应用程序的某些部分、私有和公共类成员等进行写访问的想法相同。

    要从一个主题创建一个可观察的对象,只需在任何主题上调用asObservable即可:

    let currentUserSubject$ = new BehaviorSubject() < string > 'Eric';
    let currentUser$ = currentUserSubject$.asObservable();
    

    现在我们有了一个名为currentUser$的新变量,它是currentUserSubject$的可观察序列的可观察变量。要了解其工作原理,让我们订阅currentUser observable,然后向currentUserSubject$添加一些数据:

    let currentUserSubject$ = new BehaviorSubject() < string > 'Eric';
    let currentUser$ = currentUserSubject$.asObservable();
    
    currentUserSubject$.subscribe(val => {
      console.log(val);
    });
    // => 'Eric'
    
    currentUserSubject$.next('hello');
    // => 'hello'
    

    请注意,如果您尝试调用currentUser$。next(),它将抛出一个错误,因为Observables只能观察一个序列——从而为您提供对currentUserSubject的只读访问!

    推荐文章