Angular 我可以在函数中重用可观察的对象吗?
我的问题很简单,因为我读过很多关于可观测的、订阅的文章,当然还有很多取消订阅的方法 我有这个密码Angular 我可以在函数中重用可观察的对象吗?,angular,rxjs,Angular,Rxjs,我的问题很简单,因为我读过很多关于可观测的、订阅的文章,当然还有很多取消订阅的方法 我有这个密码 merge(this.sort.sortChange, this.paginator.page) .pipe( startWith({}), switchMap(() => { this.isLoadingResults = true;
merge(this.sort.sortChange, this.paginator.page)
.pipe(
startWith({}),
switchMap(() => {
this.isLoadingResults = true;
return this.ProductionService.get__customers()
}),
map((data: QueryResult<CustomerDTO>) => {
this.isLoadingResults = false;
this.items__length = data.totalCount;
return data.records;
}),
).subscribe((data: CustomerDTO[]) => {
this.d__source = data;
});
merge(this.sort.sortChange,this.paginator.page)
.烟斗(
startWith({}),
开关映射(()=>{
this.isLoadingResults=true;
返回此.ProductionService.get\u customers()
}),
地图((数据:QueryResult)=>{
this.isLoadingResults=false;
this.items\uuu length=data.totalCount;
返回数据和记录;
}),
).订阅((数据:CustomerDTO[])=>{
此.d__源=数据;
});
这在一个名为getDataSource()的函数中
它位于函数内部,因为我想在关闭弹出按钮时手动刷新此数据源(d_u源)。让我们想象一下,在我的弹出窗口中添加了一个客户,我想关闭此弹出窗口并刷新我的数据源,向用户显示全新创建的客户
我的问题是,正如你们所看到的,我有一个sortChange和一个MatPaginator,但我遇到了一个我无法解决的错误。
我想重用这个可观察对象进行排序或分页。但是,当我关闭弹出按钮并再次调用getDataSource函数时,该函数再次订阅并获得两倍的客户,从而导致对我的API的两次HTTP GET调用
如果我在订阅部分取消订阅,就像
const subscription = merge(this.sort.sortChange, this.paginator.page)
.pipe(
startWith({}),
switchMap(() => {
this.isLoadingResults = true;
return this.ProductionService.get__customers()
}),
map((data: QueryResult<CustomerDTO>) => {
this.isLoadingResults = false;
this.items__length = data.totalCount;
return data.records;
}),
).subscribe((data: CustomerDTO[]) => {
this.d__source = data;
subscription.unsubscribe();
});
const subscription=merge(this.sort.sortChange,this.paginator.page)
.烟斗(
startWith({}),
开关映射(()=>{
this.isLoadingResults=true;
返回此.ProductionService.get\u customers()
}),
地图((数据:QueryResult)=>{
this.isLoadingResults=false;
this.items\uuu length=data.totalCount;
返回数据和记录;
}),
).订阅((数据:CustomerDTO[])=>{
此.d__源=数据;
订阅。取消订阅();
});
我不能使用排序功能
如果你有任何想法,我都会很感激的,我已经在这里面呆了一段时间了
事先谢谢 一个丑陋的解决方案是将“const subscription”组件设置为整个
this.subscription
,并在订阅之前检查如果(!this.subscription.closed)this.subscription.unsubscripte()
,然后再次调用您的订阅。但这是一个丑陋的方法,可能有更好的选择
另一种方法是简单地继承你已经得到的东西。如果在弹出关闭()上,您希望刷新d_u源代码,并且这取决于this.sort.sortChange、this.paginator.page
,我假设这两个都是主题,并且您可以控制它们,您可以只下一步调整它们的当前值吗?只需刷新呼叫。。。还是有点难看,但比前一个好
我实际上要做的最后一次尝试是创建一个BehaviorSubject,它触发了d__源代码更新。。。像这样
private updateHandler = new BehaviorSubject({}); // notice it already starts with a value
...
this.updateHandler // this onInit, and only once
.pipe(
switchMap(() => {
this.isLoadingResults = true;
return this.ProductionService.get__customers()
}),
map((data: QueryResult<CustomerDTO>) => {
this.isLoadingResults = false;
this.items__length = data.totalCount;
return data.records;
}),
).subscribe((data: CustomerDTO[]) => {
this.d__source = data;
subscription.unsubscribe();
});
这样他们也在做同样的事情
你可以用另一个主题来控制它们的结束,我们称之为“this.destroy$”
private destroy$ = new Subject();
然后,您可以通过管道连接到所有的takeUntil(this.destroy$)
(flavorfull),并添加这个onDestroy
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
最后,无论在哪里控制弹出按钮关闭,只要
this.updateHandler.next()
就可以了。如何统一可观察对象的位置(如服务或父组件)。并在任何你想要的地方订阅。只需将“share()”添加到管道中,以防止重复的服务器调用。您考虑过类似的事情吗<代码>合并(排序更改、页面、关闭弹出按钮);您将订阅该obs一次(例如在ngOnInit
),最终在ngondestry
中取消订阅,closeFlyout
将是一个主题,每当用户关闭该弹出按钮时,该主题就会发出。谢谢,伙计!答案很好,有几个备选方案,但我在“更好”的解决方案中遇到了一个错误。它说“this.updateHandler.next()”应该提供一个参数,但不知道是什么参数。你能给我解释一下吗?再次感谢!啊,对不起,是的,因为行为主体总是希望有东西发出。。。如果传递null,它应该可以工作,因为您使用的不是发射的内容,而是发射。请让我知道它是否适合你this.updateHandler.next(null)
我想你也可以把它作为一个主题,在任何地方做同样的事情(添加回管道startWith)。。。希望我对主体和可观察物的使用有一点了解,不会让你对不同的选择产生更多的困惑
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}