我已经找到了解决方法,但是我仍然很想知道是什么原因造成的。我正在为此项目使用Angular 7。
我试图对服务中的对象数组进行排序,然后将经过排序的数组通过主题传递给组件。由于某种原因,组件始终会收到未排序的数组。该阵列是通过Websocket从服务器提供的。
本质上,代码看起来像这样
private sortedData: Data[] = [];
private dataSubject= new BehaviorSubject<Data[]>([]);
//The component is subscribed to this observable
public data$ = this.dataSubject.asObservable();
public getData() { // Called from the component class
this.apiService('command', this.callback)
}
private callback = (err: any, data: Object[]): void => {
if (err) {
//Error handling code, irrelevant to the problem
} else {
this.sortedData = data.sort((a,b) => a.order - b.order);
this.dataSubject.next(this.sortedData);
}
}
我尝试过的一些东西
Object.assing([],data);
将数据值分配给临时变量并操纵温度setTimeout(()=> this.dataSubject.next(this.sortedData) ,500)
apiService
返回Observable
而不是使用回调上述所有方法均无效。当我在开发控制台中使用ng.probe()
检查服务中数组的值时,我可以看到该列表确实不是
这是踢脚线。当我将this.dataSubject.next(this.sortedData);
注释掉时,该数组突然被排序。
我通过为sortedData
添加吸气剂并完全删除BehaviorSubject
来使其工作。
我完全不知道是什么原因造成的,但是我想知道。
编辑
Here是问题代码的简化版本。我无法重现我们的问题,但是有了这个,您将可以更清楚地看到结构。该示例与应用程序之间的唯一区别是,我们在ApiService
中使用了Socket.io。
就像我上面说的,我们确实解决了这个问题,但我只是想知道是什么原因造成的。
答案 0 :(得分:0)
FWIW,我今天遇到了这个问题,并试图对其进行调试。在我的情况下,预订主题的组件是一个表行排序器,并通过另一个键对发出的数组进行(重新)排序(因为我想通过引用来对它进行排序)。
我的解决方案是发出已排序数组的副本,因为我在其他地方需要原始已排序数组。
这可能对您或其他人有帮助。仔细查看订户对发出的值的处理方式,以及未排序的数组是否按其他属性排序。
答案 1 :(得分:-1)
尝试使用rxjs方式将这种排序逻辑包含在服务中,那么您就不需要任何辅助主题。
定义getData()
方法的位置
this.apiService('command', this.callback).pipe(
map((data) => {
const sorted = data.sort((a, b) => a.order - b.order)
return sorted;
})
);
然后您可以在组件中直接订阅它,或将其分配给Observable变量以html呈现
ngOnInit(): void {
this.data$ = this.apiService.getData();
// then use it in html: <div *ngFor="let item of (data$ | async)">{{item.order}}</div>
// or subscribe to it in the component
this.apiService.getData().subscribe((data) => {
this.data = data;
})
}