angular - 在这种特殊情况下使用 async-pipe 而不是 subscribe() 真的更好吗?
问题描述
在我的组件中,我得到一个 Observable 作为@Input()。
如果 Observable 的值发生变化,我必须展开/折叠 ng-bootstrap 手风琴。所以我真的不需要模板中的 Observable 值。
这是代码,我已经有了:
零件:
@Input() urlParam$!: Observable<string>;
@ViewChild('acc') accordion!: NgbAccordion;
urlParamChange$!: Observable<string>;
ngAfterViewInit(): void {
this.urlParamChange$ = this.urlParam$.pipe(
tap(urlParam => this.synchronizeAccordion(urlParam))
);
}
synchronizeAccordion(urlParam: string): void {
// do something with this.accordion
}
在模板中,我通过异步管道订阅了新创建的 urlParamChange$:
<ng-container *ngIf="(urlParamChange$ | async)"></ng-container>
<ngb-accordion #acc="ngbAccordion">
....
</ngb-accordion>
由于我真的不需要 urlParamChange$ 的值,所以我把它放在一个自己的 ng-container 中,这样完全独立,但仍然会调用同步手风琴的方法。
我认为,上述实现并不是那么好。您将操作拆分为两个不同的文件(需要组件中的点击 + 模板中的异步管道)。
下面的方式不是更好吗?我不会在异步管道的帮助下订阅,而是直接在 ngAfterViewInit() 中订阅()。这样,我可以删除附加变量 urlParamChange$ 并且实现全部在 ngAfterViewInit() 方法中。
零件:
@Input() urlParam$!: Observable<string>;
@ViewChild('acc') accordion!: NgbAccordion;
ngAfterViewInit(): void {
this.urlParam$.subscribe(urlParam => this.synchronizeAccordion(urlParam));
}
synchronizeAccordion(urlParam: string): void {
// do something with this.accordion
}
在模板中,额外的 ng-container 被移除:
<ngb-accordion #acc="ngbAccordion">
....
</ngb-accordion>
在我看来,这两种实现都应该以完全相同的方式工作。根据最佳实践,我认为应该首选第一个解决方案。但第二个是更清洁的 IMO。
那么实现这种用例的最佳方法是什么?
解决方案
我建议您采用方法 2。通过您自己的录取,它似乎更清晰,更容易遵循。
想象一下将来有人出现,他们看到一个ng-container
带有async
绑定但没有内容的随机数。假设不再使用它,他们很可能决定将其删除,在这种情况下,您的整个tap
操作将不再运行,并且不会抛出任何错误来提醒您这一点。
而通读方法 2 的人可以很容易地看到正在发生的事情,并且修改订阅的结果是显而易见的。
手动取消订阅并没有错,您只需要确保您这样做!
推荐阅读
- javascript - 如何让文本和按钮与响应式设计的背景图像重叠?
- excel - 我无法让我的宏循环遍历列以执行我需要的操作
- ruby - 如何在运行时在冰糕中的`T::Struct`上动态定义`prop`s?
- firebase - 这个谷歌云功能会导致firestore触发器无限循环吗?
- amazon-web-services - 如何在 aws 检查器资源组上多次使用相同的标签
- node.js - nodeJs中的路由-我的路由不起作用的原因是什么?
- raspberry-pi - 我怎么知道这不是病毒?
- c++ - 在 Visual Studio 2019/2022 中构建之前可以删除特定文件吗
- java - 如何使用 Spring Reactive webflux 在 Mongodb 中保存 excel 文件的数据?
- javascript - vuetify - 根据按钮的状态更改 v-select 项目