Перетаскивание Angular Material между списками, если нет модели данных - PullRequest
0 голосов
/ 10 января 2019

Обновление:

Я создал 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>

Я ожидал бы, что смогу свободно переупорядочивать панели в обеих колонках, а также между ними. Вместо этого я могу перетащить панели, но как только я уронил одну, ничего не происходит, она возвращается в исходное состояние.

Полагаю, это потому, что позади нет модели данных. В примере s перетаскиваемые элементы div отображаются на странице с помощью *ngFor из массива. И есть также привязанный к ним метод компонента drop(event: CdkDragDrop<string[]>), который обновляет модель данных каждый раз, когда происходит отбрасывание.

Но моя проблема в том, что у меня есть не просто элементы списка, которые я мог бы поместить в некоторый массив, а целые части веб-сайта с большим количеством HTML-кода внутри, которые я хочу перетащить.

Как я могу создать модель данных для него? (если это действительно, что Angular отсутствует)

Ответы [ 2 ]

0 голосов
/ 12 января 2019

См. ответ по причине, по которой он не работал, а также пример , как перетаскивание правильно выполняется с использованием 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);
    }
  }

}
0 голосов
/ 10 января 2019

Сначала, чтобы соединить все списки, вы можете использовать следующее (я не уверен, что это может решить вашу проблему перетаскивания сброса):

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

Должен отображаться на сайте угловых компонентов.

В настоящее время вы создаете статические значения, и если у вас есть динамические значения, которые можно генерировать, то использование * ngFor с большой вероятностью будет предпочтительным.

Содержимое в списках будет оставаться таким же, как отображается. Таким образом, используя * ng, вы создаете на одном шаблоне способ отображения элемента в списке. Для этого вы можете иметь разные «шаблоны» в каждом dropList. Если оба списка подключены / связаны, это позволит вам передавать контент независимо от того, что именно, но отображаемый контент, скорее всего, останется тем же, что и шаблон.

Я не могу точно сказать, как вы можете обрабатывать динамические данные, которые не определены, но вы, вероятно, можете классифицировать тип данных, которые вы хотите обрабатывать, и создать шаблон для них. Затем воспользуйтесь * ngIF и отобразите данные по желанию, если они определенного типа.

...