【问题标题】:Angular - DragDropModule not working inside templatesAngular - DragDropModule 在模板中不起作用
【发布时间】:2021-09-10 13:14:45
【问题描述】:

我想将 DragDropModule 用于我的 Angular 应用程序,这样我就可以移动存储在 模板 中的面板(出于实际目的以及递归绘制子元素)。

我遇到的问题是,如果 cdkDrag 隐藏在模板中并且没有直接嵌套在 HTML 元素下,则 cdkDrag 找不到要放入的正确 cdkDropList。示例:

<div
cdkDropList
[cdkDropListData]="expanded.activities"
(cdkDropListDropped)="dropActivity($event)">

    <div *ngFor="let activity of expanded.activities">
        <ng-container [ngTemplateOutlet]="orangeProgramActivity"></ng-container>
    </div>
</div>

<ng-template #orangeProgramActivity>
    <div cdkDrag>This is just a test</div>
</ng-template>

使用此代码示例,可以将 orangeProgramActivity 拖动到任何地方,但不会拖放到正确的 dropList 中,因为 cdkDrag 关键字无法在其自己的模板中找到任何 droplist。

在第二个示例中,一切正常,项目被放入正确的 dropList:

<div
cdkDropList
[cdkDropListData]="expanded.activities"
(cdkDropListDropped)="dropActivity($event)">

    <div *ngFor="let activity of expanded.activities">
        <div cdkDrag>This is just a test</div>
    </div>
</div>

我想实现与第二个示例相同的功能,但使用模板,因为我确实需要它们进行递归。不幸的是,我无法透露整个代码,因为我的雇主不会对此感到满意。

我需要的只是模板内的 cdkDrag 的一些静态引用,以使用模板外的 dropList 指向正确的元素。

这些是我在互联网上找到的唯一解决方案,它们似乎对我不起作用: Material 7 Drag and Drop ng-template incompatibility CdkDragDrop and ngTemplateOutlet

这是我关于 Stack Overflow 的第一个问题,而且我是 Angular 新手,所以对于我的帖子中的任何混淆,我深表歉意,并提前感谢您的帮助!

【问题讨论】:

    标签: html angular typescript


    【解决方案1】:

    这可能不适用于所有用例,但您可以这样写:

    <div
    cdkDropList
    [cdkDropListData]="expanded.activities"
    (cdkDropListDropped)="dropActivity($event)">
    
        <div *ngFor="let activity of expanded.activities" cdkDrag>
            <ng-container [ngTemplateOutlet]="orangeProgramActivity"></ng-container>
        </div>
    </div>
    
    <ng-template #orangeProgramActivity>
        <div>This is just a test</div>
    </ng-template>
    

    【讨论】:

    • 是的,这似乎是唯一不错的选择,但如果我们至少可以在模板中为更复杂的结构创建句柄,那将非常有用。我想我将创建另一个带有句柄图标和模板的容器,并使用 CSS 我将把句柄设置为我想要的位置。完成后我会在这里发布结果。
    【解决方案2】:

    我很幸运我只需要在它们所在的数组中重新排序元素,我不需要将它们转移到其他容器中。因此,对于我的“根”活动,我使用了您的简单解决方案将其全部包装在一个可拖动的元素中。

    <div cdkDropList [cdkDropListData]="expanded.activities" (cdkDropListDropped)="dropActivity($event)">
    
    <!-- For every object in array make a container with template and an icon that will serve as a handle -->
    <div *ngFor="let activity of expanded.activities">
    
        <div cdkDrag>
            <div cdkDragHandle>
                <!-- Handle icon from FontAwesome -->
                <i class="fas fa-grip-vertical"></i>
            </div>
    
            <!-- Container with a template that we need -->
            <ng-container [ngTemplateOutlet]="orangeProgramActivity" [ngTemplateOutletContext]="{act: activity}"></ng-container>
        </div>
        <!-- Recursive template for children -->
        <ng-container [ngTemplateOutlet]="childActivitiesRecursion" [ngTemplateOutletContext]="{act: activity}"></ng-container>
    
    </div>
    

    对于我的递归,我在模板中创建了一个下拉列表,它仅用于重新排序这些子活动。 (我在粘贴模板时遇到问题,因此 ng-template 标记不会在代码末尾终止)

    <ng-template let-act="act" #childActivitiesRecursion>
    
    <!-- Droplist inside a template for reordering child activites -->
    <div cdkDropList [cdkDropListData]="act.childActivities" (cdkDropListDropped)="dropActivity($event)">
    
        <!-- Iterates through all child activities -->
        <div *ngFor="let childActivity of act.childActivities">
    
            <div cdkDrag>
                <div cdkDragHandle>
                    <i class="fas fa-grip-vertical"></i>
                </div>
                <!-- Different template for child activities -->
                <ng-container [ngTemplateOutlet]="blueProgramActivity" [ngTemplateOutletContext]="{act: childActivity}"></ng-container>
            </div>
            <!-- Recursion for even deeper child activites -->
            <ng-container [ngTemplateOutlet]="childActivitiesRecursion" [ngTemplateOutletContext]="{act: childActivity}"></ng-container>
    
        </div>
    </div>
    

    我会接受理查德的回答作为解决方案,因为如果您能够像这样解决它,那绝对是您能做的最优雅的解决方案。但是如果你需要在使用模板进行递归之后将项目转移到不同的容器中,仍然会有一个问题!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-27
      • 2021-07-12
      • 1970-01-01
      • 2017-11-15
      • 1970-01-01
      • 1970-01-01
      • 2020-07-25
      • 1970-01-01
      相关资源
      最近更新 更多