我正在尝试使用与 Angular Material 7 相关的拖放功能。
我将我的模板分成可重复使用的部分ngTemplateOutlet
,每个选项都可以是Thing ™ 或嵌套的Thing ™,它们有更多的 sub-Things ™。
Nested Things ™ 显示为扩展面板。我希望所有第一级的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>
问题:单个Things ™ 是可拖动的,但它们并没有像 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>
而且,当然为什么不呢,它有效!是的,很好,但为什么呢?
没有太大变化,我们使用 angIf
而不是第一个,并删除了ThingngTemplateOutlet
™的上下文绑定,因为由于共享范围,现在两个模板都有其局部变量引用。
那么,为什么它以第二种方式而不是第一种方式工作呢?
加分点:是否有可能让它保持第一个代码结构,在我看来,它显然更易读和更干净?