【问题标题】:is it "safe" to expose your RxJS Subjects to the "outside world"将您的 RxJS 主题暴露给“外部世界”是否“安全”
【发布时间】:2019-02-12 20:01:02
【问题描述】:

我读了这篇好文章 Angular onPush Change Detection Strategy

他在某个地方写道:

通过使用 asObservable() 方法将您的主题暴露给外部世界是一种反模式,始终暴露可观察对象。

但他没有解释原因。这是否意味着我不应该做这样的事情?

export class ExampleComponent {

  public drawerTrigger$ = new Subject<{}>(); 
}

在 HTML 中

  <button  class="hamburgher-button" type="button"
     (click)="drawerTrigger$.next($event)">
    <i >menu</i>
  </button>

如果不是,那是正确的方法?

【问题讨论】:

  • 1.是的,就是这个意思。 2. 在引用中已经回答:“总是通过使用 asObservable() 方法公开可观察对象。”
  • 好的,但是怎么做呢?如果我执行 const test$ = this.drawerTrigger$.asObservable(); 之类的操作,我将无法在 HTML 中调用 test$.next($event),并且如果我没有将 drawerTrigger$ 设置为公共,我将无法在 HTML 中使用它(AoT 编译失败)
  • 所以你有两个属性,一个私有主题和一个公共可观察对象。参见例如我写的这篇博文:blog.jonrshar.pe/2017/Apr/09/async-angular-data.html

标签: angular typescript rxjs


【解决方案1】:

一般来说,您不应该公开Subjects,因为这会使任何使用您的服务的人有可能无法控制地调用drawerTrigger$.next(),即使在不正确​​的用例中也是如此。

最糟糕的情况是任何人都可以使用drawerTrigger$.error()drawerTrigger$.complete()。主题具有内部状态,如果它们发出 errorcomplete,主题将被标记为已停止并且永远不会发出任何内容。如果您公开您的Subject,那么您就可以让任何人发出这些通知。

官方推荐的从 TypeScript 类中公开 Subjects 的方法只是将它们的类型强制为Observable。你不需要使用asObservable()(RxJS 本身不会在其代码库的任何地方内部使用asObservable()):

export class ExampleComponent {
  private drawerTriggerSubject = new Subject<{}>(); 
  public drawerTrigger$: Observable<{}> = this.drawerTriggerSubject;
}

【讨论】:

  • 感谢您的回答,但在 HTML 中我应该简单地使用一个包装抽屉TriggerSubject.next($event) 的函数?
  • 您最好将主题设为私有,然后创建一个发出值 public onClick(e): void { drawerTrigger$.next(e); } 的方法,然后在模板中调用 onClick($event)
  • 出于好奇,是什么阻止了exampleComponent['drawerTriggerSubject'].next()
  • @tricheriche 什么都没有,你也可以这样做,(drawerTrigger$ as any).next()
  • 所以正如我在回答中所说,它更像是一种智能感知方便? (以及您解释的“良好做法”,即使可以解决)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-30
  • 2021-01-26
相关资源
最近更新 更多