Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

184
Views
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 answers
Answer question

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!