Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 我可以在函数中重用可观察的对象吗?_Angular_Rxjs - Fatal编程技术网

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();
}