【问题标题】:How to re-order Angular Material Table?如何重新订购 Angular 材料表?
【发布时间】:2019-06-05 00:20:23
【问题描述】:

目标:使用 Angular Material 创建一个可以使用 Angular Drag & Drop 修改的表格。

预期行为:表格应在拖放时重新排序

当前行为:行是可拖动的,并且底层数据源的顺序会发生变化,但是当该行被删除时,它会重新回到其在表格中的原始位置。

看这个例子:

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 应用已更新。

【问题讨论】:

  • 样式不佳是由于没有包含主题,只需将@import '@angular/material/prebuilt-themes/deeppurple-amber.css';(或任何其他主题)添加到您的styles.css。
  • 这是有道理的,它解决了样式问题。谢谢。

标签: angular drag-and-drop angular-material


【解决方案1】:

正如您在编辑中提到的,您确实需要在每次修改数据源时调用renderRows()。它甚至在 Angular Material 文档here 中被提及。

根据表的最新数据集呈现行,这些数据要么是 直接作为输入提供或通过 Observable 检索 流(直接或来自数据源)。检查中的差异 自上次比较以来的数据仅执行必要的更改 (添加/删除/移动行)。

如果表的数据源是 DataSource 或 Observable,这将是 每次提供的 Observable 流发出一个 新的数据数组。 否则如果你的数据是一个数组,这个函数会 需要调用才能呈现任何更改。

为了绕过每次调用renderRows(),您可以做的是将您的数据源转换为可观察对象并在您的onListDrop() 函数中发出一个新值,以便每次拖放一行时表格都会自动更新。

【讨论】:

  • 我最终听从了您的建议,并将 dataSource 更改为 Observable (BehaviorSubject)。但是我遇到了新问题。我已经更新了帖子。
【解决方案2】:

您遇到angular/material2 issue #14056“cdkDropList:event.previousIndex 在第二次移动时没有更新”。问题中详细介绍了深度克隆数据源的解决方法,它是 cmets。

看看here,在对控制台日志稍作更改后,我在哪里玩你的演示 (console.log(`Moving item[${event.previousIndex}] "${this.items[event.previousIndex]}" to index ${event.currentIndex}`))

我将“Item 0”从索引 0 拖到索引 3。索引 0 处的项目移动到索引 3。✔️
我将“项目 0”从索引 3 拖到索引 1。索引 0 处的项目移动到索引 1。✖️
我将“Item 0”从索引 3 拖到索引 2。索引 0 处的项目移动到索引 2。✖️

event.previousIndex 在移动到不同索引后错误地保持不变。

【讨论】:

  • 这似乎适用于简单的数据源,但当 mat 表源是 Observable 时则不行。深度克隆如何与 Observable 一起使用?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-08-01
  • 2018-01-16
  • 1970-01-01
  • 2021-09-28
  • 1970-01-01
  • 2018-04-02
  • 2016-11-22
相关资源
最近更新 更多