角度CDK拖放:嵌套的下拉列表

时间:2020-02-18 13:01:34

标签: angular angular-material

我正在尝试建立一个demo app,可以在其中计划学生及其书桌。当一个教室有太多桌子时,我可以将它们放在另一个教室中。然后,我可以计划这些桌子上的学生。我使用<div class="row IDE_container"> <div class="col-lg-3 col-md-3 col-sm-3"> <div class="bg"> <img src="myImage1.png" class="IDE_div" /> </div> </div> <div class="col-lg-2 col-md-2 col-sm-2"> <div class="circle_bg circle_bg_sm"> <img src="myImage2.png" class="IDE_div" /> </div> </div> <div class="col-lg-3 col-md-3 col-sm-3"> <div class="circle_bg"> <img src="myImage3.png" class="IDE_div" /> </div> </div> </div> .bg{ background-color: #ededed; border-radius: 100%; text-align: center; padding: 35% 5%; width: max-content; max-width: 100%; box-shadow: 0 0 3px 1px #DDD; } .IDE_div { display: inline-block; position: relative; width: 100%; height: 100%; } .IDE_container { display: flex; align-items: baseline; } 是因为教室的数量是动态的。

当我将学生的书桌放到“未分配的”学生列表中时,书桌仍保留在教室中,但学生却按预期方式进入列表。 但是,当我尝试将学生放到桌子上时,谓词(只允许将产品放到列表中)不允许。但是,当我删除谓词时,该学生将被放到教室列表中,而不是桌子上。

将学生拖到课桌的工作正常:

Proper functioning of the app

将学生拖到桌子上失败:

Failing part

我需要帮助,尤其是将学生放到桌子上而不是教室上,导致dropStudent触发。

我认为将办公桌的容器提高到更高的Z索引可能会有所帮助,但这没有用。

引用:

1 个答案:

答案 0 :(得分:2)

您需要在未分配的学生列表上使用cdkDropListConnectedTo选项,并添加桌面列表的所有实例。这是因为CdkDropListGroup仅查看同级列表,而不查看子级列表:

您需要向您的桌面下拉列表添加模板引用,以便您可以在组件ts中查询此模板,也可以使用ID字符串。我认为模板参考的用途更加广泛,但为了举例,我将使用id:

<div cdkDropList 
      id="{{studentList.listName}}" 
      [cdkDropListData]="studentList.student"
      class="example-list"
      (cdkDropListDropped)="returnStudent($event)"
      [cdkDropListEnterPredicate]="userReturnPredicate"
      [cdkDropListConnectedTo]="desks">
  <div  *ngFor="let person of studentList.student"
        class="example-box" 
        cdkDrag
        [cdkDragData]="person">
    {{person.userName}}
  </div>
</div>

如您所见,cdkDropListConnectedTo已绑定desks。在您的组件中,您可以这样定义办公桌:

desks: string[] = [];

this.desks = this.projectLists.map(
  (list) => list.products.map((product) => product.productName)
).flat(2);

要使其与ViewChildren一起使用,您的ngAfterViewInit中需要这样的内容:

ngAfterViewInit(): void {
  this.deskLists.changes.pipe(
    startWith(true),
    tap(() => {
      this.desks = this.deskLists.toArray();
      this.cd.markForCheck();
      this.cd.detectChanges();
    }),
  ).subscribe();
}

working example