我正在尝试使用Angular Material 7发布的拖放功能。
我使用ngTemplateOutlet
将我的模板分成可重用的部分,每个选项都可以是一个Thing™或具有更多子Thing™的嵌套Thing™。
嵌套的Thing™显示为扩展面板。我希望所有一级Things™都可以像列表一样重新排序。
(好吧,好吧,显然这是一个带有普通和嵌套选项的可重新排序侧边栏,假装它不是那么明显)
这是我最初编写的代码。
<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
放回“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
™的内容绑定,因为现在两个模板都有其本地变量引用,感谢共享作用域。
为什么第二种方式能够起作用而第一种不能呢?
额外加分:是否可能保持第一种代码结构使其工作,因为对我来说,这种方式显然更易读和干净?