Перетаскивание Angular Material между списками, если нет модели данных
Обновить:
Я создал стек, чтобы воспроизвести проблему.
Рассмотрим следующий статический шаблон, который у меня есть:
<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 ответа
Посмотрите этот ответ по причине, почему он не работал, и вот также пример того, как перетаскивание правильно осуществляется с помощью 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);
}
}
}
Сначала, чтобы соединить все списки, вы можете использовать следующее (я не уверен, что это может решить вашу проблему с перетаскиванием сброса):
<div cdkDropListGroup>
<!-- All lists in here will be connected. -->
<div cdkDropList *ngFor="let list of lists"></div>
</div>
Он должен отображаться на сайте угловых компонентов.
В настоящее время вы создаете статические значения, и если у вас есть динамические значения, которые можно генерировать, то использование * ngFor с большой вероятностью будет предпочтительным.
Содержимое в раскрывающихся списках останется таким же, как и отображаемое. Таким образом, используя * ng, вы создаете на одном шаблоне способ отображения элемента в списке. Для этого вы можете иметь разные "шаблоны" в каждом dropList. Если оба списка подключены / связаны, это позволит вам передавать контент, несмотря ни на что, но отображаемый контент, скорее всего, останется тем же, что и шаблон.
Я не могу точно сказать, как вы можете обрабатывать динамические данные, которые не определены, но вы, вероятно, можете классифицировать тип данных, которые вы хотите обрабатывать, и создать шаблон для них. Затем воспользуйтесь *ngIF и отобразите данные по желанию, если они определенного типа.