2

更新:

我创建了一个stackblitz来重现这个问题。


考虑我拥有的以下静态模板:

<div class="websiteleftColumn" cdkDropList #left="cdkDropList"
  [cdkDropListConnectedTo]="[right]">
    <div class="panelWithMuchContent" cdkDrag> much HTML </div>
    <div class="panelWithMuchContent" cdkDrag> much HTML </div>
    <div class="panelWithMuchContent" cdkDrag> much HTML </div>
</div>

<div class="websiteRightColumn" cdkDropList #right="cdkDropList"
  [cdkDropListConnectedTo]="[left]">
    <div class="panelWithMuchContent" cdkDrag> much HTML </div>
    <div class="panelWithMuchContent" cdkDrag> much HTML </div>
    <div class="panelWithMuchContent" cdkDrag> much HTML </div>
</div>

我希望能够自由地重新排列两列以及两列之间的面板。相反,我可以拖动面板,但只要我放下一个,什么都没有发生,它会回到原来的状态。

猜测是因为后面没有数据模型。在example*ngFor中,可拖动的 div 通过数组呈现在页面上。还有一个drop(event: CdkDragDrop<string[]>)绑定到它们的组件方法,每次下降时更新数据模型。

但我的问题是,我不仅有可以放入某个数组的如此简单的列表元素,而且还有网站的整个部分,里面有很多我想拖动的 HTML 代码。

我怎样才能为它创建一个数据模型?(如果真的缺少 Angular)

4

2 回答 2

3

请参阅此答案以了解其无法正常工作的原因,这里还有一个示例ng-template如何使用s 和数据模型正确实现拖放:

import { Component, Input, ViewChild, TemplateRef } from '@angular/core';
import { CdkDragDrop, moveItemInArray, transferArrayItem } from '@angular/cdk/drag-drop';

@Component({
  selector: 'hello',
  template: `

    <div class="row" cdkDropListGroup>

      <div class="col-6" cdkDropList [cdkDropListData]="list1"
        (cdkDropListDropped)="panelDropped($event)">

        <div cdkDrag *ngFor="let p of list1">
          <ng-container *ngTemplateOutlet="this[p+'Panel']">
          </ng-container>
        </div>

      </div>

      <div class="col-6" cdkDropList [cdkDropListData]="list2"
        (cdkDropListDropped)="panelDropped($event)">

        <div cdkDrag *ngFor="let p of list2">
          <ng-container *ngTemplateOutlet="this[p+'Panel']">
          </ng-container>
        </div>

      </div>

    </div>

    <ng-template #aPanel><div class="card"></div></ng-template>
    <ng-template #bPanel><div class="card"></div></ng-template>
    <ng-template #cPanel><div class="card"></div></ng-template>
    <ng-template #dPanel><div class="card"></div></ng-template>
    <ng-template #ePanel><div class="card"></div></ng-template>
    <ng-template #fPanel><div class="card"></div></ng-template>

  `,
  styles: [`

    .col-6:nth-child(1) { background-color: plum; }
    .col-6:nth-child(2) { background-color: peru; }
    .card { background-color: blue; height: 10em; margin: 0.5em; }

  `]
})
export class HelloComponent {
  @Input() name: string;

  @ViewChild('aPanel') aPanel: TemplateRef<any>;
  @ViewChild('bPanel') bPanel: TemplateRef<any>;
  @ViewChild('cPanel') cPanel: TemplateRef<any>;
  @ViewChild('dPanel') dPanel: TemplateRef<any>;
  @ViewChild('ePanel') ePanel: TemplateRef<any>;
  @ViewChild('fPanel') fPanel: TemplateRef<any>;

  list1: Array<string> = ['a', 'b', 'c'];
  list2: Array<string> = ['d', 'e', 'f'];

  panelDropped(event: CdkDragDrop<string[]>) {
    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);
    }
  }

}
于 2019-01-12T09:55:17.937 回答
1

首先连接所有列表,您可以使用以下内容(我不确定这是否可以解决您的拖动重置问题):

<div cdkDropListGroup>
  <!-- All lists in here will be connected. -->
  <div cdkDropList *ngFor="let list of lists"></div>
</div>

它应该显示在角度组件站点上。

您当前创建的是静态值,如果您有可以生成的动态值,那么使用 *ngFor 很可能更可取。

下拉列表中的内容将与显示的内容相同。因此,使用 *ngFor 您可以在单个模板上创建您希望如何显示列表中的元素。因此,您可以在每个 dropList 中有不同的“模板”。将两个下拉列表都连接/链接后,无论如何您都可以传输内容,但显示的内容可能与模板相同。

我不能确定如何处理未定义的动态数据,但您可能可以对要处理的数据类型进行分类并为此创建模板。然后利用 *ngIF 并根据需要显示数据(如果它是某种类型)。

于 2019-01-10T13:57:53.040 回答