【问题标题】:Public service variables should be defined with a BehaviorSubject type公共服务变量应使用 BehaviorSubject 类型定义
【发布时间】:2020-01-08 12:59:04
【问题描述】:

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

这个想法是,如果您想公开一个变量,那么您很可能想要响应它们的变化(现在或不久的将来)。我在服务中添加的几乎所有公共变量似乎都是这种情况。

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

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

另一个例子:一个变量包含当前登录用户的 UI 设置。当其中一项设置发生更改时,您希望立即应用这些设置并重新渲染屏幕布局。

由于我以前没有将其作为一种模式阅读过, 这个策略是否有缺陷?如果有,为什么?

【问题讨论】:

    标签: angular typescript design-patterns behaviorsubject


    【解决方案1】:

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

    export class ConnectionService {
      private readonly isConnected = new BehaviorSubject(false);
    
      readonly isConnected$ = this.isConnected.asObservable();
    }
    

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

    @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(或任何适合您需要的状态管理系统)查看状态处理可能是一个想法

    【讨论】:

    • 很大的改进:-)。感谢您完善模式。 - 我是否正确,asObservable 仍然保留了 behaviorsubject 的最后一个值,就像您直接听 behaviorsubject 的情况一样? (因为这是当然的要求)
    • @bvdb 你是对的 :) 我做了一点stackblitz
    【解决方案2】:

    这是将Facade-Pattern 应用于服务的常用方法。当使用NgRx 时,在不同的服务中对复杂的选择器进行分组是很常见的。如果您想在 BehaviorSubject 上实现精细的访问控制,可以将其公开为 Observable,并为显式操作提供 setter。

    class Service {
    
       private isConnected$ = new BehaviorSubject(false)
    
       get isConnected(): Observable<boolean> {
          return this.isConnected$;
       }
    
       setConnectionState(connected: boolean) {
          this.isConnected$.next(connected);
       }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-06-26
      • 2020-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-08
      相关资源
      最近更新 更多