我有一个JSON对象数组包含一个order
属性;我也有一个Angular拖放列表来排序这些对象,它们的模型是这个数组。当我重新订购时,它应该会更新所有商品的order
值。这是通过我编写的以下代码完成的:
import { Component } from '@angular/core';
import { StateService } from '../services/state.service';
import {CdkDragDrop, moveItemInArray} from '@angular/cdk/drag-drop';
@Component({
selector: 'app-states',
templateUrl: './states.component.html',
styleUrls: ['./states.component.scss']
})
export class StatesComponent {
states: any[] = [
{ id: 0, order: 0, nom: 'test0' },
{ id: 1, order: 1, nom: 'test1' },
];
constructor(private statesService: StateService) { }
drop(event: CdkDragDrop<string[]>) {
moveItemInArray(this.states, event.previousIndex, event.currentIndex);
console.log(this.states);
this.states.forEach(_ => {
_.order = this.states.indexOf(_);
});
}
}
和HTML代码:
<nb-card>
<nb-card-body>
<div cdkDropList class="states_list" (cdkDropListDropped)="drop($event)">
<div class="state_element" cdkDrag *ngFor="let state of states">{{ state.nom }}</div>
</div>
</nb-card-body>
</nb-card>
<标题>重新排序一项后,调用函数drop
;后者调用moveItemInArray
,它根据用户的拖放操作移动数组states
的元素。然后我显示这个数组的内容:问题是,在这一刻,元素的order
属性的值已经改变了!然而,moveItemInArray
对任何元素的属性都不起作用(它只是移动模型的元素)。可以更新order
的代码的唯一部分是在forEach
…位于console.log
.
那么为什么console.log
显示数据的状态,考虑到forEach
中的代码,知道console.log
位于之前?
- 拖拽"test1"前"test0">
- 应该显示:"{id: 1, order: 1, nom: 'test1'} - {id: 0, order: 0, nom: 'test0'}">
- 拖拽"test1"前"test0">
- 实际显示:"{id: 1, order: 0, nom: 'test1'} - {id: 0, order: 1, nom: 'test0'}">
最小且可测试的可执行代码
- 在AngularJS空项目中,你可以简单地复制/粘贴上面的代码,并通过拖放元素和检查控制台的显示来测试它。
这里没有异步行为。
moveItemInArray
只移动模型数组中的元素;特别是,它不会改变模型元素的任何属性的值,包括这样一个属性order
您的状态是否从其他位置被更改,例如在您的StateService
或NbCardComponent
中?
当您删除这些时,它会按您的预期工作,请参阅https://stackblitz.com/edit/angular-ivy-xmsna7?file=src/app/states.component.ts