【问题标题】:Getting BehaviorSubject with ngIf Direct Access or Subscribe使用 ngIf 直接访问或订阅获取 BehaviorSubject
【发布时间】:2020-11-23 20:04:31
【问题描述】:

在 Angular 中,直接访问 BehaviorSubject 的 getValue() 与使用订阅和更新(本地?)变量以在 *ngIf 中使用相比有什么缺点?

在共享服务中:

currentState : BehaviorSubject<string> = new BehaviorSubject<string>(null);

在使用共享服务的 UI .ts 文件中:

constructor (public myservice : SharedService) { };

在 UI .html 文件中,仅在服务初始化后显示:(如果我不这样做,其中的内容将获得 currentState 的空引用:

*ngIf="myservice.currentState.getValue() != null"

或者,订阅,更新一个局部变量,并使用它来代替 myservice.getValue()。我确定有人会问,如果我要这样做,为什么还要使用 BehaviorSubject,但如果有人想在服务的价值发生变化时得到通知,他们可以这样做。有点像“如果你想要的话,基于事件的服务是可用的”,但也是基于当前用例的“如果你想要就自己访问”界面?

我做错了吗?我是使用behavioursubject的值来控制UI,所以需要使用ngIf。

【问题讨论】:

  • 两者都是不好的做法。请改用| async 管道。
  • @pascalpuetz 对不起,让我澄清一下,问题的哪一部分 | async 为我解决,对我来说是一个更好的问题 - 空引用问题?
  • 我用一个例子回答了这个问题。我将在几秒钟内添加解释为什么会更好。

标签: angular rxjs


【解决方案1】:

使用async管道的解决方案

这两种做法都不是最优的。将async 管道与控制 UI 的 Observable 一起使用被认为是最佳实践。此外,您可以使用它来更多地利用 Observables,并通过管道导入一个可以命名的新 Observable 使您的代码更具可读性。

在你的 TS 上:

@Component({...})
export class MyComponent {
   public displayWhatever$:Observable<boolean> = this.myService.currentState.pipe(
      map(state => !!state) // this is the same as != null, if you really want only "not null" use "state !== null"
   );

   constructor(private myService:SharedService){}
}

在你的 Tempate 上:

<div *ngIf="displayWhatever$ | async"></div>

<!-- If you need to use your state inside your div you can even use some syntax sugar: -->

<div *ngIf="myService.currentState | async as currentState>
   <!-- Use currentState in here as if it was a normal variable -->
</div>

为什么这样更好?

async 管道处理订阅您的 Observable 以及为您取消订阅。此外,它会根据需要触发组件更改检测。当 observable 可以在其他地方更改并且您的组件设置为 changeDetection: ChangeDetectionStrategy.OnPush 时,这通常是一个问题。它基本上与每当 observables 发出时运行 changeDetectorRef.detectChanges() 相同 - 这是您想要的,因为您可能不知道 observables 的更改位置。

【讨论】:

  • 即使使用结构而不是字符串或布尔值,我也应该能够使用它,对吗?像 currentState.showOkButton 一样,仍然享受 currentState 上的 null 保护?
  • 是的,是一样的。 map(state =&gt; !!state) 将您的状态映射到布尔值 true 当您的状态具有“真实”值时(不是:undefinednull0""(空字符串)、falseNaN,也许是我忘记了,所以广泛检查)。
  • @DanChase 在模板部分添加了另一个示例(如果您想省略中间 observable)
猜你喜欢
  • 1970-01-01
  • 2020-03-03
  • 1970-01-01
  • 2021-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多