目标:使用Angular Material创建表,可以使用Angular拖放进行修改。
预期的行为:表格应在拖放时重新排序
当前行为:行是可拖动的,并且底层数据源的顺序发生了变化,但是当删除行时,它会恢复到表中的原始位置。
请参见以下示例:
https://stackblitz.com/edit/drag-drop-reorder-mattable
如何解决/实现?
(此外,我不确定为什么它在Stackblitz中的样式这么差。那里的任何见识也将受到赞赏)
编辑:我发现了一种超级hacky的方式来使行以正确的顺序再次呈现,但是这是无法实现的。我只是将t.renderRows()
放在drop事件处理程序之后执行。见下面的实线
<mat-table #t
cdkDropList
(cdkDropListDropped)="onListDrop($event); t.renderRows()"
[dataSource]="dataSource"
class="mat-elevation-z8">
...
</mat-table>
编辑2: 我已经完成了使用rxjs的简单重构,并且每个元素的第一次拖放重新排序都非常有效。但是,当我尝试移动已经移动了一次的元素时,没有得到预期的行为。 Stackblitz应用程序已更新。
答案 0 :(得分:3)
您遇到angular/material2 issue #14056“ cdkDropList:event.previousIndex不会在第二步更新”。问题及其注释中详细介绍了深克隆数据源的一种解决方法。
在对控制台日志(1. Hello
2. My name is khan
3. When
4. What
5. Opted bat
6. Learn
)进行少量更改之后,看看here在我的演示中的播放情况
我将“项目0”从索引0拖到索引3。索引0处的项目移动到索引3。✔️
我将“项目0”从索引3拖到索引1。索引0的项目移至索引1。✖️
我将“项目0”从索引3拖动到索引2。索引0的项目移至索引2。✖️
2. My name is khan
3. When
4. What
5. Opted bat
在移动到另一个索引后错误地保持不变。
答案 1 :(得分:2)
正如您在编辑中提到的那样,每次修改数据源时,确实需要调用renderRows()
。甚至在Angular Material文档here中也提到了这一点。
根据表的最新数据集来呈现行, 直接作为输入提供或通过Observable检索 流(直接或从数据源)。检查是否存在差异 自上次差异以来的数据仅执行必要的更改 (添加/删除/移动行)。
如果表的数据源是DataSource或Observable,则将是 每次提供的Observable流发出一个 新数据数组。 否则,如果您的数据是数组,则此函数将 需要调用以呈现任何更改。
您可以做什么来解决每次调用renderRows()
的问题,就是将数据源转换为Observable并在onListDrop()
函数中发出一个新值,以便每次您拖动/放一行。