Angular CDK 拖放列表在数据重新实例化时中断
Angular CDK drag and drop lists break when their data is re-instantiated
我有一个带有多个 table 的 cdkDropListGroup(使用 mat-table 指令),我正在尝试设置拖放,以便 table 中的元素可以重新排列或拖到另一个 table。但是,当重新实例化拖放列表的数据时,该项目不会拖动,并且会在控制台中记录错误。 Here 是一个重现问题的堆栈闪电战。尝试在 table 秒之间或 table 秒内拖动行几次,应该会出现错误,并且每隔几次尝试拖放就会卡住。如何解决这个问题,因为在我的实际代码中,此数据来自某些 http 服务,必须重新实例化,并且每次将项目拖放到新位置时都必须重新填充 tables?
https://stackblitz.com/edit/angular-e3ajdt
这是我看到的错误。
zone.js:192 Uncaught TypeError: Cannot read property '_getSiblingContainerFromPosition' of undefined
at DragRef._updateActiveDropContainer (drag-ref.ts:727)
at SafeSubscriber.DragRef._pointerMove [as _next] (drag-ref.ts:505)
at SafeSubscriber.__tryOrUnsub (Subscriber.ts:270)
at SafeSubscriber.next (Subscriber.ts:212)
at Subscriber._next (Subscriber.ts:141)
at Subscriber.next (Subscriber.ts:101)
at Subject.next (Subject.ts:68)
at HTMLDocument.handler (drag-drop-registry.ts:127)
at ZoneDelegate.invokeTask (zone.js:421)
at Zone.runTask (zone.js:188)
DragRef._updateActiveDropContainer @ drag-ref.ts:727
DragRef._pointerMove @ drag-ref.ts:505
SafeSubscriber.__tryOrUnsub @ Subscriber.ts:270
SafeSubscriber.next @ Subscriber.ts:212
Subscriber._next @ Subscriber.ts:141
Subscriber.next @ Subscriber.ts:101
Subject.next @ Subject.ts:68
handler @ drag-drop-registry.ts:127
ZoneDelegate.invokeTask @ zone.js:421
Zone.runTask @ zone.js:188
ZoneTask.invokeTask @ zone.js:496
invokeTask @ zone.js:1540
globalZoneAwareCaptureCallback @ zone.js:1598
setTimeout (async)
scheduleTask @ zone.js:2075
ZoneDelegate.scheduleTask @ zone.js:407
Zone.scheduleTask @ zone.js:232
Zone.scheduleMacroTask @ zone.js:255
scheduleMacroTaskWithCurrentZone @ zone.js:1114
(anonymous) @ zone.js:2090
proto.(anonymous function) @ zone.js:1394
hostReportError @ hostReportError.ts:7
SafeSubscriber.__tryOrUnsub @ Subscriber.ts:276
SafeSubscriber.next @ Subscriber.ts:212
Subscriber._next @ Subscriber.ts:141
Subscriber.next @ Subscriber.ts:101
Subject.next @ Subject.ts:68
handler @ drag-drop-registry.ts:127
ZoneDelegate.invokeTask @ zone.js:421
Zone.runTask @ zone.js:188
ZoneTask.invokeTask @ zone.js:496
invokeTask @ zone.js:1540
globalZoneAwareCaptureCallback @ zone.js:1598
preview-ee4d58d6ef0576b4e139b.js:1 Unhandled Promise rejection: Cannot read property 'getItemIndex' of undefined ; Zone: <root> ; Task: Promise.then ; Value: TypeError: Cannot read property 'getItemIndex' of undefined
at eval (drag-ref.ts:710)
at ZoneDelegate.invoke (zone.js:388)
at Object.onInvoke (ng_zone.ts:273)
at ZoneDelegate.invoke (zone.js:387)
at Zone.run (zone.js:138)
at NgZone.run (ng_zone.ts:171)
at DragRef._cleanupDragArtifacts (drag-ref.ts:700)
at eval (drag-ref.ts:577)
at ZoneDelegate.invoke (zone.js:388)
at Zone.run (zone.js:138) TypeError: Cannot read property 'getItemIndex' of undefined
at eval (https://angular-e3ajdt.stackblitz.io/turbo_modules/@angular/cdk@7.3.0/bundles/cdk-drag-drop.umd.js:895:56)
at ZoneDelegate.invoke (https://angular-e3ajdt.stackblitz.io/turbo_modules/zone.js@0.8.26/dist/zone.js:388:26)
at Object.onInvoke (https://angular-e3ajdt.stackblitz.io/turbo_modules/@angular/core@7.1.0/bundles/core.umd.js:16186:37)
at ZoneDelegate.invoke (https://angular-e3ajdt.stackblitz.io/turbo_modules/zone.js@0.8.26/dist/zone.js:387:32)
at Zone.run (https://angular-e3ajdt.stackblitz.io/turbo_modules/zone.js@0.8.26/dist/zone.js:138:43)
at NgZone.run (https://angular-e3ajdt.stackblitz.io/turbo_modules/@angular/core@7.1.0/bundles/core.umd.js:16100:32)
at DragRef._cleanupDragArtifacts (https://angular-e3ajdt.stackblitz.io/turbo_modules/@angular/cdk@7.3.0/bundles/cdk-drag-drop.umd.js:883:22)
at eval (https://angular-e3ajdt.stackblitz.io/turbo_modules/@angular/cdk@7.3.0/bundles/cdk-drag-drop.umd.js:363:23)
at ZoneDelegate.invoke (https://angular-e3ajdt.stackblitz.io/turbo_modules/zone.js@0.8.26/dist/zone.js:388:26)
at Zone.run (https://angular-e3ajdt.stackblitz.io/turbo_modules/zone.js@0.8.26/dist/zone.js:138:43)
通过注入 angular 的 ChangeDetectorRef 并在每次在 populateDataSource 方法中重新实例化数据时调用 detectChanges() 来修复此问题。
我有一个带有多个 table 的 cdkDropListGroup(使用 mat-table 指令),我正在尝试设置拖放,以便 table 中的元素可以重新排列或拖到另一个 table。但是,当重新实例化拖放列表的数据时,该项目不会拖动,并且会在控制台中记录错误。 Here 是一个重现问题的堆栈闪电战。尝试在 table 秒之间或 table 秒内拖动行几次,应该会出现错误,并且每隔几次尝试拖放就会卡住。如何解决这个问题,因为在我的实际代码中,此数据来自某些 http 服务,必须重新实例化,并且每次将项目拖放到新位置时都必须重新填充 tables?
https://stackblitz.com/edit/angular-e3ajdt
这是我看到的错误。
zone.js:192 Uncaught TypeError: Cannot read property '_getSiblingContainerFromPosition' of undefined
at DragRef._updateActiveDropContainer (drag-ref.ts:727)
at SafeSubscriber.DragRef._pointerMove [as _next] (drag-ref.ts:505)
at SafeSubscriber.__tryOrUnsub (Subscriber.ts:270)
at SafeSubscriber.next (Subscriber.ts:212)
at Subscriber._next (Subscriber.ts:141)
at Subscriber.next (Subscriber.ts:101)
at Subject.next (Subject.ts:68)
at HTMLDocument.handler (drag-drop-registry.ts:127)
at ZoneDelegate.invokeTask (zone.js:421)
at Zone.runTask (zone.js:188)
DragRef._updateActiveDropContainer @ drag-ref.ts:727
DragRef._pointerMove @ drag-ref.ts:505
SafeSubscriber.__tryOrUnsub @ Subscriber.ts:270
SafeSubscriber.next @ Subscriber.ts:212
Subscriber._next @ Subscriber.ts:141
Subscriber.next @ Subscriber.ts:101
Subject.next @ Subject.ts:68
handler @ drag-drop-registry.ts:127
ZoneDelegate.invokeTask @ zone.js:421
Zone.runTask @ zone.js:188
ZoneTask.invokeTask @ zone.js:496
invokeTask @ zone.js:1540
globalZoneAwareCaptureCallback @ zone.js:1598
setTimeout (async)
scheduleTask @ zone.js:2075
ZoneDelegate.scheduleTask @ zone.js:407
Zone.scheduleTask @ zone.js:232
Zone.scheduleMacroTask @ zone.js:255
scheduleMacroTaskWithCurrentZone @ zone.js:1114
(anonymous) @ zone.js:2090
proto.(anonymous function) @ zone.js:1394
hostReportError @ hostReportError.ts:7
SafeSubscriber.__tryOrUnsub @ Subscriber.ts:276
SafeSubscriber.next @ Subscriber.ts:212
Subscriber._next @ Subscriber.ts:141
Subscriber.next @ Subscriber.ts:101
Subject.next @ Subject.ts:68
handler @ drag-drop-registry.ts:127
ZoneDelegate.invokeTask @ zone.js:421
Zone.runTask @ zone.js:188
ZoneTask.invokeTask @ zone.js:496
invokeTask @ zone.js:1540
globalZoneAwareCaptureCallback @ zone.js:1598
preview-ee4d58d6ef0576b4e139b.js:1 Unhandled Promise rejection: Cannot read property 'getItemIndex' of undefined ; Zone: <root> ; Task: Promise.then ; Value: TypeError: Cannot read property 'getItemIndex' of undefined
at eval (drag-ref.ts:710)
at ZoneDelegate.invoke (zone.js:388)
at Object.onInvoke (ng_zone.ts:273)
at ZoneDelegate.invoke (zone.js:387)
at Zone.run (zone.js:138)
at NgZone.run (ng_zone.ts:171)
at DragRef._cleanupDragArtifacts (drag-ref.ts:700)
at eval (drag-ref.ts:577)
at ZoneDelegate.invoke (zone.js:388)
at Zone.run (zone.js:138) TypeError: Cannot read property 'getItemIndex' of undefined
at eval (https://angular-e3ajdt.stackblitz.io/turbo_modules/@angular/cdk@7.3.0/bundles/cdk-drag-drop.umd.js:895:56)
at ZoneDelegate.invoke (https://angular-e3ajdt.stackblitz.io/turbo_modules/zone.js@0.8.26/dist/zone.js:388:26)
at Object.onInvoke (https://angular-e3ajdt.stackblitz.io/turbo_modules/@angular/core@7.1.0/bundles/core.umd.js:16186:37)
at ZoneDelegate.invoke (https://angular-e3ajdt.stackblitz.io/turbo_modules/zone.js@0.8.26/dist/zone.js:387:32)
at Zone.run (https://angular-e3ajdt.stackblitz.io/turbo_modules/zone.js@0.8.26/dist/zone.js:138:43)
at NgZone.run (https://angular-e3ajdt.stackblitz.io/turbo_modules/@angular/core@7.1.0/bundles/core.umd.js:16100:32)
at DragRef._cleanupDragArtifacts (https://angular-e3ajdt.stackblitz.io/turbo_modules/@angular/cdk@7.3.0/bundles/cdk-drag-drop.umd.js:883:22)
at eval (https://angular-e3ajdt.stackblitz.io/turbo_modules/@angular/cdk@7.3.0/bundles/cdk-drag-drop.umd.js:363:23)
at ZoneDelegate.invoke (https://angular-e3ajdt.stackblitz.io/turbo_modules/zone.js@0.8.26/dist/zone.js:388:26)
at Zone.run (https://angular-e3ajdt.stackblitz.io/turbo_modules/zone.js@0.8.26/dist/zone.js:138:43)
通过注入 angular 的 ChangeDetectorRef 并在每次在 populateDataSource 方法中重新实例化数据时调用 detectChanges() 来修复此问题。