无法读取未定义的属性 - cdkDropListData 拖放角材料

Posted

技术标签:

【中文标题】无法读取未定义的属性 - cdkDropListData 拖放角材料【英文标题】:Cannot read property of undefined - cdkDropListData drag-drop Angular Material 【发布时间】:2019-05-21 13:52:37 【问题描述】:

我正在使用新的 Angular 7 Material CDK 拖放功能将项目从一个列表移动到另一个列表,并且在移动这些项目时,视觉上一切都在晃动,但是当通过列表更改项目时,我收到一条错误消息,提示无法获取未定义的属性(列表数组),即使我使用的是“item?.array”的东西

在构造函数中:

this.userService.getUserById('some-user-id').subscribe(user => 
  this.user1 = user;
  console.log(user1.route.routePoints); // I see the array in log
);

this.userService.getUserById('some-other-user-id').subscribe(user => 
  this.user2 = user;
  console.log(user2.route.routePoints); // I see the array in log
);

在将项目从列表拖动到另一个列表时,出现错误“无法读取未定义的属性 'routePoints'”

<div cdkDropList #routeA="cdkDropList" cdkDropListOrientation="horizontal" 
[cdkDropListData]="user1?.route?.routePoints"
class="list" (cdkDropListDropped)="drop($event, false, user1)" 
[cdkDropListConnectedTo]="[queue, routeB]">

这里是拖拽代码:

drop(event: CdkDragDrop<RoutePoint[]>, fromQueue: boolean = false, user: User) 
  if (event.previousContainer === event.container) 
    moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
   else 
    transferArrayItem(event.previousContainer.data, event.container.data, event.previousIndex, event.currentIndex);
  
  this.userService.updateUser(user);

【问题讨论】:

请检查模板中,cdkDropListData 在拖动的那一刻指向一个有效的数组(不是未定义的)。可能是其他一些函数将数组重置为未定义(因为它可能发生在 cdkDropListEnterPredicate 处理程序中)。空数组将是有效的。也许你可以用它开始调试。 【参考方案1】:

正如marcinolawski@https://github.com/angular/components/issues/15948提到的,原因是:

问题在于 _DragRef.initialContainer == 未定义。这是因为 _DragRef.initializeDragSequence() 的调用早于 _DragRef.withDropContainer()。 _initializeDragSequence() 基于 _dropContainer 初始化 _initialContainer,_dropContainer 由 _withDropContainer() 初始化,但是因为 _initializeDragSequence() 早于 _withDropContainer() 被调用,所以 _initialContainer 被设置为 undefined。更多信息:https://github.com/angular/components/blob/master/src/cdk/drag-drop/drag-ref.ts

一个丑陋但可行的解决方法是触发 AfterViewChecked 上的更改检测,如下所示(由 lukaszgodula @ 上面的同一 github):

ngAfterViewChecked() 
   this.cdRef.detectChanges();

当然还有将 ChangeDetectorRef 注入到组件中:

constructor(
   private cdRef: ChangeDetectorRef

【讨论】:

【参考方案2】:

确保先初始化user1数组

user: yourType = ;

this.userService.getUserById('some-user-id').subscribe(user => 
  this.user1 = user;
  console.log(user1.route.routePoints); // I see the array in log
); 

【讨论】:

【参考方案3】:

我收到此错误是因为我的 cdkDropListData 元素不是 cdkdrag 元素的直接父元素,导致问题之间存在选项卡元素。它的 ng 版本 7.x

【讨论】:

以上是关于无法读取未定义的属性 - cdkDropListData 拖放角材料的主要内容,如果未能解决你的问题,请参考以下文章

`无法读取未定义的属性(读取'组件')`

NextJS:未捕获的类型错误:无法读取未定义的属性(读取“属性”)

使用地图时反应'无法读取未定义的属性'

如何使用自定义错误消息捕获“TypeError:无法读取未定义的属性(读取'0')”?

查询返回错误“无法读取未定义的属性(读取'节点')”

无法读取未定义的“已触及”属性