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

187
Vistas
El comportamiento de Angular cdkDragDrop cambió con la actualización de Angular, la interfaz de usuario ya no se actualiza cuando comienza el arrastre

Tenemos un componente que tiene elementos que se pueden arrastrar y soltar, usamos el módulo de arrastrar/soltar de CDK para administrar esto.

Parte de la funcionalidad es cambiar una propiedad del objeto subyacente cuando el usuario comienza a arrastrar. Para actualizar la interfaz de usuario, llamamos a ChangeDetectorRef.detectChanges().

Cuando estaba en la versión 9 de Angular, esto funcionó bien, sin embargo, desde que se actualizó a la versión 12.1, la interfaz de usuario ya no se actualiza hasta que se suelta el elemento arrastrado y no puedo encontrar una manera de hacerlo funcionar.

Aquí hay una versión simplificada del componente:

HTML:

 <div cdkDropList> <div cdkDrag (cdkDragStarted)="onCdkDragStarted($event)" *ngFor="let step of steps">Step: {{step.id}} {{step.text}}</div> </div>

Código:

 import { ChangeDetectorRef, Component} from '@angular/core'; @Component({ selector: 'drag-poc', templateUrl: 'drag-poc.component.html', styles: [] }) export class DragPocComponent { steps: any[] = [ { id: 1, text: '' }, { id: 2, text: '' }, { id: 3, text: '' }, { id: 4, text: '' }, { id: 5, text: '' }, ]; constructor(private ref: ChangeDetectorRef){ } onCdkDragStarted($event){ // this is just a hack to get a reference to the array object that is being dragged const draggedItem = $event.source.__ngContext__[8].ngForOf[$event.source.__ngContext__[8].index]; draggedItem.text = "MOVED"; this.ref.detectChanges(); } }

Con Angular 9, la interfaz de usuario se actualiza una vez que comienza el arrastre:

Arrastrar con la interfaz de usuario actualizada

Con Angular 12 (o 13), el código es exactamente el mismo, pero la interfaz de usuario no se actualiza hasta que se suelta el elemento arrastrado:

Arrastrar con IU no actualizada

¿Hay alguna manera de actualizar la interfaz de usuario una vez que comience el arrastre?

Stackblitz Angular 9: https://stackblitz.com/edit/angular-ivy-s4pmmm

StackBlitz último angular: https://stackblitz.com/edit/angular-ivy-ztdufb

EDITAR: el último Angular StackBlitz se actualiza para mostrar el problema después de la respuesta de @Eliseo

problema actualizado

about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

Me temo que necesita crear un *cdkDragPreview . Y un cdkDrag es un poco ?@X##??!! porque debes tener en cuenta varias cosas: el tamaño del arrastre, el punto en el que arrastras el elemento...

Para tener en cuenta todo esto suelo crear dos variables

 style: any = null; offset:any=null

Y el uso de cdkDrag (cdkDragMoved) y (mousedown) -también necesita usar (cdkDragStarted) y posible (cdkDragEnded) para que su .html se vuelva como

 <div cdkDropList class="example-list" (cdkDropListDropped)="drop($event)"> <div class="example-box" *ngFor="let movie of movies;let i=index" cdkDrag [cdkDragData]="movie" (cdkDragStarted)="onDragStarted($event,i)" (cdkDragMoved)="onDragMove($event)" (cdkDragEnded)="onDragEnded($event,i)" (mousedown)="setStyle($event)" >{{movie.title}}{{movie.text}} <div *cdkDragPreview class="example-box" [ngStyle]="style"> {{movie.title}}{{movie.text}} </div> </div> </div>

y los .ts

 drop(event: CdkDragDrop<any[]>) { moveItemInArray(this.movies, event.previousIndex, event.currentIndex); } onDragStarted(event:CdkDragStart<any>,index:number) { //you can use this.movies[index].text="moved" //or use event.source.data.text="moving...." } onDragEnded(event:CdkDragEnd<any>,index:number) { this.movies[index].text="" } setStyle(event: MouseEvent) { const rect = (event.target as HTMLElement).getBoundingClientRect(); this.style = { width: rect.width + 'px', height: rect.height + 'px'} this.offset={x:event.offsetX,y:event.offsetY }; } public onDragMove(event: CdkDragMove<any>): void { const el=(document.getElementsByClassName('cdk-drag-preview')[0])as any const xPos = event.pointerPosition.x - this.offset.x; const yPos = event.pointerPosition.y - this.offset.y; el.style.transform = `translate3d(${xPos}px, ${yPos}px, 0)`; }

Vea en el stackblitz cómo paso el "índice" a las funciones (onDragStarted) y (onDragEnded) para cambiar la matriz de "objeto" (no necesita usar algún complejo como $event.source.__ngContext__[8].ngForOf[$eve....

NOTA: También puede verificar la propiedad event.source o event.source.element para obtener el elemento HTML, también puede agregar una propiedad cdkDragData a su Drag

about 4 years ago · Juan Pablo Isaza 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