Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

295
Vistas
Angular - DragDropModule not working inside templates

I would like to use DragDropModule for my angular application so I can move panels that are stored inside templates (for practical purposes as well as for recursive plotting of child elements).

The problem that I have is that cdkDrag can't find the correct cdkDropList to drop into if cdkDrag is hidden within a template and is not directly nested under the HTML element. Example:

<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>

With this code example, the orangeProgramActivity can be dragged anywhere but doesn't drop into the correct dropList as cdkDrag keyword can't find any droplist within its own template.

In the second example, everything works correctly and the item gets dropped into correct 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>

I would like to achieve the same functionality as in the second example, but with the use of templates because I really need them for recursion. Unfortunately, I can't reveal the whole code as my employer wouldn't be happy with that.

All I need is some static reference for my cdkDrag that is inside a template, to point onto a correct element with dropList that is outside of the template.

These are the only solutions that I found on the internet and they don't seem to work for me: Material 7 Drag and Drop ng-template incompatibility CdkDragDrop and ngTemplateOutlet

This is my first question on Stack Overflow and I'm new to angular, so I'm sorry for any confusion in my post, and thanks for any help in advance!

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

This might not work for all use cases, but you could just write it like this:

<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>
over 4 years ago · Santiago Trujillo Denunciar

0

I was lucky that I only need to reorder elements inside an array in which they are and I don't need to transfer them into other containers. So for my "root" activities, I used your simple solution to wrap it all in a draggable element.

<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>

And for my recursion, I created a droplist inside a template that serves only for reordering these children activities. (I had problems with pasting template so the ng-template tag is not terminated at the end of the code)

<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>

I will accept Richard's answer as a solution because if you are able to solve it like this, it's definitely the most elegant solution you can do. But there would be still an issue if you needed to transfer items into different containers after using templates for recursion!

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda