角cdkDropList拖动元素限制

时间:2018-11-25 15:06:24

标签: javascript html angular drag-and-drop angular-cdk

我目前正在使用Angular 2和来自https://material.angular.io/cdk/drag-drop/overview的拖放模块。我已经使拖放功能起作用。我希望将两种类型的类对象限制为它们自己的拖放列表类型。

这很可能可以通过将列表分组来解决,但是由于我正在使用递归,因此出现了其他问题...

当前,我将每个列表都放在同一组中,这意味着可以在每个列表中拖放任何内容(cdkDropListGroup,在执行递归部分之前已放置在组件中)。

我试图将列表限制为仅接受元素或属性(但不能同时接受),但是我不知道如何执行此操作...

我有以下内容:

课程:

export class Attribute {
name: string;
type: string;

}

export class Element {
    id: number;
    name: string;
    elements: Element[]
    attributes: Attribute[];

}

HTML:

<div > 
Elements             
<div
  cdkDropList    
  [cdkDropListData]="elements"
  class="example-list"
  (cdkDropListDropped)="drop($event)"
  [cdkDropListEnterPredicate]="isElement">
<div type="button" text-align="right" class="btn btnNotInline" (click)="addNewElement()">
  <img src="assets/img/IconPlus.png" class="elementListIcon"></div>
<div *ngFor="let element of elements" class="example-box" cdkDrag>
  <mat-list>
    <mat-list-item> 
      <mat-form-field appearance="standard dense" class="example-container">
        <input matInput placeholder="{{element.name}}"> 
      </mat-form-field>
    </mat-list-item>
    <mat-list-item>
      <div
        cdkDropList
        [cdkDropListData]="attributes"
        class="cdk-drag-list-attributes"
        (cdkDropListDropped)="drop($event)"
        [cdkDropListEnterPredicate]="isAttribute">
        <div type="button" text-align="right" class="btn btnNotInline" (click)="addNewAttribute()">
          <img src="assets/img/IconPlusPurple.png" class="elementListIcon"></div>
        <div *ngFor="let attribute of attributes" class="example-container" cdkDrag>
          <p class="mat-input-element-attribute">  
            <input matInput placeholder="{{attribute.name}}">
            <input matInput placeholder="{{attribute.type}}">
          </p> 
        </div>
      </div>
    </mat-list-item>
    <mat-list-item> 
        <app-listboardelement [attributes]="element.attributes" [elements]="element.elements"></app-listboardelement>
    </mat-list-item>
  </mat-list>
</div>

ts。被调用的方法(属性看起来很相似)

isElement(drag : CdkDrag){
      console.log("check " + (drag instanceof Element) +  typeof drag + " , "+ typeof drag.data + ", "+ drag.data + " , " +(drag.data instanceof Element));
      return (drag.data instanceof Element);
    }
我从输出中得到的

我只是得到:“检查false object,undefined,undefined,false” 由此,我试图将拖动的对象与一个类进行比较。但是我没有任何运气。

有什么办法可以动态地将拖动对象限制为某些列表?我知道[cdkDropListConnectedTo],但这给了我与递归和绑定有关的问题。任何指导将不胜感激

编辑: 添加了用于演示其显示方式的图像-但无法正常工作; enter image description here

2 个答案:

答案 0 :(得分:0)

您始终可以检查拖放的“起源于目的地”容器并采取相应的措施,例如:

  drop(event: CdkDragDrop<string[]>) {
    // same container (just reorder items)
    if (event.previousContainer === event.container) {
        moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
    } else {
        // from first list to second list
        if (event.previousContainer.id === 'cdk-drop-list-0' && event.container.id === 'cdk-drop-list-1') {
            // do something
        }
        // from second list to first list
        if (event.previousContainer.id === 'cdk-drop-list-1' && event.container.id === 'cdk-drop-list-0') {
            // do something
        }
    }
}

希望这会有所帮助!

答案 1 :(得分:0)

<块引用>

ts。方法被调用(属性看起来很像)

isElement(drag : CdkDrag){
     console.log("check " + (drag instanceof Element) +  typeof drag + " , "+ typeof drag.data + ", "+ drag.data + " , " +(drag.data instanceof Element));
     return (drag.data instanceof Element);
   }

drag.data 不起作用,因为您没有通过 cdkDrag

将任何数据分配给您的 [cdkDragData]
<div *ngFor="let element of elements" class="example-box" cdkDrag [cdkDragData]="element">
 ...
</div>

对于您的问题...您可以为元素和属性创建两组 cdkDropList 数组并使用 [cdkDropListConnectedTo] 绑定连接列表组或将所有列表连接到一个数组中并允许删除您已经提到的 [cdkDropListEnterPredicate]="isElement"

要解决递归问题,您需要执行一些额外的步骤并检查当前放置的容器是否正确。

我在关于嵌套的问题中有详细说明。

Angular Nested Drag and Drop / CDK Material cdkDropListGroup cdkDropList nested