将您的RxJS主题暴露给"外部世界"是否"安全"?

ALG*_*GDB 3 rxjs typescript angular

我读了一篇关于Angular onPush Change Detection Strategy的好文章

他在写道:

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

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

export class ExampleComponent {

  public drawerTrigger$ = new Subject<{}>(); 
}
Run Code Online (Sandbox Code Playgroud)

并在HTML中

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

如果不是,这是正确的方法吗?

mar*_*tin 12

一般情况下,您不应暴露Subjects,因为这使得任何使用您的服务的人都可能无法控制地调用,drawerTrigger$.next()即使在不正确​​的用例中也是如此.

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

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

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

  • 您最好将主题设置为私有,然后创建一个发出值 `public onClick(e): void { sliderTrigger$.next(e); 的方法。}` 然后在模板中调用 `onClick($event)` (2认同)
  • 如果您在任何地方使用“as any”,那么您的代码就会出现问题,因为您这样做显然是为了避免 TypeScript 类型。同样的原因也是 tslint 通常不允许使用 exampleComponent['drawerTriggerSubject']` 的原因,因为没有理由使用它,除非你想避免 TypeScript 检查(如果你需要使用这些,那么你不需要使用 TypeScript根本没有)。 (2认同)