Я пытаюсь использовать функции перетаскивания, связанные с угловым материалом 7.
Я разделил свой шаблон на куски многократного использования, используя ngTemplateOutlet
, и каждая опция может быть либо Вещью ™, либо вложенной Вещью ™, в которой есть некоторые дополнительные элементы . ™.
Вложенные Вещи ™ отображаются в виде панели расширения.
Я хочу, чтобы все элементы Things ™ первого уровня были переупорядочены, как если бы они были списком.
( Хорошо, хорошо, очевидно, что это переставляемый sidenav с обычными и вложенными параметрами, просто притворитесь, что это не так очевидно )
Это код, который я изначально написал.
<div cdkDropList (cdkDropListDropped)="dropItem($event)" lockAxis="y">
<ng-container *ngFor="let thing of things">
<ng-container
*ngTemplateOutlet="!thing.children ? singleThing : multipleThing; context: { $implicit: thing }"
></ng-container>
</ng-container>
</div>
<ng-template #singleThing let-thing>
<div cdkDrag>
<ng-container *ngTemplateOutlet="thingTemplate; context: { $implicit: thing }"></ng-container>
</div>
</ng-template>
<ng-template #multipleOption let-thing>
<mat-expansion-panel cdkDrag (cdkDropListDropped)="dropItem($event)">
<mat-expansion-panel-header>
<mat-panel-title>
<p>Nested thing title</p>
<span cdkDragHandle></span>
</mat-panel-title>
</mat-expansion-panel-header>
<ng-container *ngFor="let childThing of thing.children">
<div class="childThing">
<ng-container *ngTemplateOutlet="thingTemplate; context: { $implicit: childThing }"></ng-container>
</div>
</ng-container>
</mat-expansion-panel>
</ng-template>
<ng-template #thingTemplate let-thing>
<p>I'm a thing!</p>
<span cdkDragHandle></span>
</ng-template>
Проблема: одиночные Вещи ™ можно перетаскивать, но они не приводятся в исполнение как список, как должен делать cdkDropList, я могу просто перетаскивать их повсюду.
У меня была похожая проблема некоторое время назад, когда попытка использовать выходы шаблонов и возврат ng-template
s обратно в «поток HTML» помогли решить эту проблему, поэтому я попробовал то же самое.
<div cdkDropList (cdkDropListDropped)="dropItem($event)" lockAxis="y">
<ng-container *ngFor="let thing of things">
<ng-container
*ngIf="!thing.children; then singleThing; else multipleThing"
></ng-container>
<ng-template #singleThing>
<div cdkDrag>
<ng-container *ngTemplateOutlet="thingTemplate; context: { $implicit: thing }"></ng-container>
</div>
</ng-template>
<ng-template #multipleOption>
<mat-expansion-panel cdkDrag (cdkDropListDropped)="dropItem($event)">
<mat-expansion-panel-header>
<mat-panel-title>
<p>Nested thing title</p>
<span cdkDragHandle></span>
</mat-panel-title>
</mat-expansion-panel-header>
<ng-container *ngFor="let childThing of thing.children">
<div class="childThing">
<ng-container *ngTemplateOutlet="thingTemplate; context: { $implicit: childThing }"></ng-container>
</div>
</ng-container>
</mat-expansion-panel>
</ng-template>
</ng-container>
</div>
<ng-template #thingTemplate let-thing>
<p>I'm a thing!</p>
<span cdkDragHandle></span>
</ng-template>
И, конечно, почему бы и нет, это работает!
Да, хорошо, но почему ?
Немного изменившись, мы использовали ngIf
вместо первого ngTemplateOutlet
и удалили привязки контекста для Thing ™, потому что теперь оба шаблона имеют ссылку на локальную переменную благодаря общей области действия.
Итак, почему именно он работает вторым способом, а не первым?
Бонусные баллы: возможно ли заставить его работать, сохраняя первую структуру кода, которая, на мой взгляд, кажется более читаемой и чистой?