Arrays 发出已排序数组会导致数组本身取消排序
我已经想出了一个解决办法,但我仍然很想知道是什么导致了这一点。我在这个项目中使用Angular 7 我试图对服务中的对象数组进行排序,然后将排序后的数组通过主题传递给组件。由于某些原因,组件总是收到未排序的数组。该阵列是通过websocket从服务器提供的 本质上代码是这样的Arrays 发出已排序数组会导致数组本身取消排序,arrays,angular,typescript,Arrays,Angular,Typescript,我已经想出了一个解决办法,但我仍然很想知道是什么导致了这一点。我在这个项目中使用Angular 7 我试图对服务中的对象数组进行排序,然后将排序后的数组通过主题传递给组件。由于某些原因,组件总是收到未排序的数组。该阵列是通过websocket从服务器提供的 本质上代码是这样的 private sortedData: Data[] = []; private dataSubject= new BehaviorSubject<Data[]>([]); //The component i
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);
}
}
private-sortedData:Data[]=[];
私有数据主体=新行为主体([]);
//该组件订阅了该可观察的
公共数据$=this.dataSubject.asObservable();
从组件类调用public getData(){//
this.apiService('command',this.callback)
}
私有回调=(错误:any,数据:Object[]):void=>{
如果(错误){
//错误处理代码,与问题无关
}否则{
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
,而不是使用回调可观察的
- 编写自己的排序函数
- 上述所有因素的组合
ng.probe()
来检查服务中数组的值时,我可以看到列表确实不正确
这是踢球的人。当我评论this.dataSubject.next(this.sortedData)时代码>输出时,数组突然被排序
我通过为sortedData
添加一个getter并删除BehaviorSubject
实现了这一点
我完全不知道这可能是什么原因,但我想知道
编辑
是问题代码的简化版本。我无法重现我们的问题,但有了这个,你可以更清楚地看到结构。该示例与我们的应用程序之间的唯一区别是,我们在ApiService
中使用Socket.io
正如我上面所说,我们确实解决了这个问题,但我只是想知道是什么原因造成了这个问题。尝试使用rxjs方式将这个排序逻辑包含在服务中,那么您就不需要任何助手主题了
您在其中定义了getData()
方法
this.apiService('command', this.callback).pipe(
map((data) => {
const sorted = data.sort((a, b) => a.order - b.order)
return sorted;
})
);
然后在您的组件中,您可以直接订阅它,或者将它分配给一个可观察的变量以在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;
})
}
ngOnInit():void{
this.data$=this.apiService.getData();
//然后在html中使用它:{{item.order}
//或者在组件中订阅它
this.apiService.getData().subscribe((数据)=>{
这个数据=数据;
})
}
FWIW,我今天遇到了这个问题,并试图调试它。在我的例子中,订阅主题的组件是一个表行排序器,并通过另一个键(因为我猜它是通过引用)对发出的数组进行(重新)排序
我的解决方案是发出排序数组的副本,因为我需要在其他地方使用原始排序数组
也许这对你或其他人有帮助。查看订户对发出的值做了什么,以及未排序的数组是否按其他属性排序。您的“问题”缺少很多信息。当它“不起作用”时,通常99%的时间都是编码器的错误。这意味着你的代码就是问题所在:如果你没有提供你所创建的完整代码,我们无法告诉你为什么它表现得很糟糕。考虑提供一个ON,以便我们可以在Accon中看到它。回调是未定义的更改GETDATA方法:<代码>。ApService(“命令”,这个。回调)< /Calth>我的坏。这在实际的代码中。我也尝试在stackblitz上重新创建这个。如果我能让它重现这个,我会发布这个例子。我真的很难理解你的演示,你正在将一个未排序和排序的数组传递给组件,所以在我看来是正确的,这意味着模板显示的数据是正确的。我们最终做的几乎就是这样。