Angular Cdk拖放,常量长度列表

4
我已经在这个问题上苦思冥想了相当长的时间。我想要实现的是具有恒定长度的两个连接的拖放列表。这意味着,如果我将一个元素从一个列表移动到另一个列表,另一个列表会增加一个项目。当然,在cdkDropListDropped事件期间实现这一点是微不足道的,但我希望它在拖动项目到列表上时立即发生。
我的大多数尝试都涉及使用cdkDropListEntered事件来尝试:
1. 尝试简单地移动数据数组中的项目:
public enter(list: number, event: CdkDragEnter<User[]>) {
  if (list === 0) {
    let data = this.schedule.responsible.pop();
    this.schedule.queue.unshift(data);
  } else {
    let data = this.schedule.queue.shift();
    this.schedule.responsible.push(data);
  }
}

这导致了以下类型的错误:

core.js:6185 ERROR DOMException:未能在此节点的子级中找到要插入新节点的节点,因此无法执行“insertBefore”

第二种尝试使用 CdkDropListaddItem()removeItem()getSortedItems()。这导致类似的问题。
第三种尝试使用 Renderer2 移动 DOM 元素本身(并保留数据不变)。
有没有办法实现我想要的效果?这里这个精美的绘画帮助解释了我想要实现的效果。
1个回答

2
好的,我经过尝试两个解决方案后弄清楚了。第一个方法涉及向两个列表添加占位符框,只有在它们有内容时才可见。它们的内容将是推入该列表的框的内容。同时,原始框被赋予了display: none样式。这基本实现了我想要的行为,但由于可拖动对象的内部模型与DOM之间的不匹配,存在一些视觉问题。

最终成功的方法是放弃首先拥有两个列表的概念。然后排序自然解决。但是,样式必须稍微以不同的方式进行处理,因为每个可拖动对象都需要是列表的直接子代。

附上代码和一个工作的Stackblitz示例:

app.component.ts

import { Component, OnInit} from '@angular/core';
import {CdkDragDrop, CdkDropList, moveItemInArray } from '@angular/cdk/drag-drop';


@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit {

    public lists: {list1: string[], list2: string[]};
    public fullList: string[];
    public numList1: number;

    constructor() {}

    ngOnInit() {
        this.lists = {
            list1: ['one', 'two'],
            list2: ['three', 'four']
        };
        this.fullList = this.lists.list1.concat(this.lists.list2);
        this.numList1 = this.lists.list1.length;
    }

    public drop(event: CdkDragDrop<string[]>) {
        moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
    }
}

app.component.html

<div class="list-container">
  <div cdkDropList
      [cdkDropListAutoScrollDisabled]="true"
      [cdkDropListData]="fullList"
      cdkDropListLockAxis="y"
      (cdkDropListDropped)="drop($event)">
    <ng-container *ngFor="let item of fullList; let index = index;">
      <h2 *ngIf="index === 0">List 1</h2>
      <h2 *ngIf="index === numList1">List 2</h2>
      <div cdkDrag class="drop-box">{{item}}</div>
    </ng-container>
  </div>
</div>

Stackblitz:https://stackblitz.com/edit/angular-ivy-s7zfye

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接