Public 服务变量应该定义为 BehaviorSubject 类型

Public service variables should be defined with a BehaviorSubject type

在服务BehaviorSubject类型上创建public变量作为标准方法是个好主意吗。

想法是,如果你想创建一个变量 public,你很可能想要响应它们的变化(现在或不久的将来)。我在服务中添加的几乎每个 public 变量似乎都是这种情况。

我开始更改某些变量的类型,因为我不得不这样做,现在我开始将其视为某种模式。

一个例子 是一个public 变量,它保存连接状态。 isConnected。当服务连接中断时,您希望向最终用户显示一个弹出消息,并在连接恢复时使其消失。

另一个例子:一个变量包含当前登录用户的UI设置。当这些设置之一发生变化时,您希望立即应用这些设置并重新呈现屏幕布局。

因为我以前没有读过这个作为一种模式, 此策略是否出于某种原因存在缺陷?如果是,为什么?

BehaviorSubject 公开为 public 或任何 Subject 可以作为下一个(是动词吗?)通常不是一个好主意。这样你将部分地向外界暴露服务的目的,而只有服务应该负责做事。所以最好是使用 .asObservable() 方法。这将 return 一个没有主题部分的 Observable:

export class ConnectionService {
  private readonly isConnected = new BehaviorSubject(false);

  readonly isConnected$ = this.isConnected.asObservable();
}

然后一个组件或另一个服务可以监听这个可观察对象,而不能直接更新它:

@Component({
  template: `
    <div *ngIf="!(isConnected$ | async)" class="popup">Oh no!</div>
  `
})
export class ConnectionPopupComponent {
  readonly isConnected$ = this.cs.isConnected$;

  constructor(private cs: ConnectionService) {}
}

当您的应用变大,或者您希望它及时变大时,使用 ngrx 或 ngxs(或任何适合您需要的状态管理系统)查看状态处理可能是个好主意

这是一种常用的应用方法 Facade-Pattern to a service. When using NgRx 在不同的服务中对复杂的选择器进行分组是很常见的。如果您想在 BehaviorSubject 上实现细粒度的访问控制,您可以将其 public 设为 Observable 并为显式操作提供设置器。

class Service {

   private isConnected$ = new BehaviorSubject(false)

   get isConnected(): Observable<boolean> {
      return this.isConnected$;
   }

   setConnectionState(connected: boolean) {
      this.isConnected$.next(connected);
   }

}