Drag and Drop com Angular Material e DropList dinâmica

Que tal descobrimos juntos como fazer essa dificílima tarefa?

Que bom que aceitou o meu desafio 😁

Já precisou criar um drag and drop com uma lista de objetos e não quis implementar cada DropList em um trecho html diferente? Eu também e por este motivo criei um simples exemplo de como utilizar o drag and drop do Angular Material com este intuito.

Mas o que tem de extraordinário nisso?

Nada de mais! Rsrs, mas na maioria dos exemplos que você vai encontrar cada DropList tem um respectivo trecho html, já aqui não, as DropList's são inseridas dinamicamente no html ao iterarmos numa lista de objetos.

Pressupostos!

  • Irei do ponto de partida de que você já sabe criar e configurar um projeto Angular IO

  • Explicarei apenas como foi implementado a solução. Por este motivo leia atentamente a documentação do site Angular Material - Drag and Drop

  • Vale lembrar que as bibliotecas utilizadas e suas respectivas versões estão disponíveis no package.json

  • Você deve clonar o projeto de exemplo, mas se ainda não fez isso fique tranquilo que vou esperar você acessar o link a seguir😴mat-drag-and-drop-example

Inicializando a aplicação

$ ng serve

Após carregar acesse http://localhost:4200/ e divirta-se arrastando e soltando.

Mas, e agora?

Agora vamos entender o que foi feito no código. A tela inicial é composta por três arquivos:

  • drag-and-drop.component.html

  • drag-and-drop.component.ts

  • drag-and-drop.component.css

Nós iremos focar apenas no ".html" e no ".ts", pois o ".css" está idêntico a qualquer exemplo de drag and drop com mais de uma DropList no site do Angular Material.

Senhoras e senhores lhes apresento o ".html"

drag-and-drop.component.html
<div class="margin-custom">
  <!-- Iterando numa lista para criar os cdkDropList's. 
    São os elemento que contém os itens que pode ser arrastados -->
  <div class="example-container" 
    *ngFor="let zoologico of zoologicos; let i = index">
    <h2>{{'Lista de soltar ' + (i + 1)}}</h2>
    <div class="example-list" 
      (cdkDropListDropped)="drop($event)" 
      [cdkDropListConnectedTo]="nomesDropList"
      [cdkDropListData]="zoologico.animais" 
      id="{{zoologico.nome}}" cdkDropList>

      <!-- Criando os cdkDrag's. São os itens que podem ser arrastados -->
      <div class="example-box" 
          *ngFor="let animal of zoologico.animais" cdkDrag>
        <span>{{animal}}</span>
      </div>
    </div>
  </div>
</div>

A diferença desse para os demais exemplo é que o utilizamos o atributo id para identificar a DropList deste modo podemos criá-las através da iteração em uma lista.

Agora vamos para o ".ts"

drag-and-drop.component.ts
import { Component } from '@angular/core';
import { CdkDragDrop, moveItemInArray, transferArrayItem } from '@angular/cdk/drag-drop';

@Component({
  selector: 'app-drag-and-drop',
  templateUrl: './drag-and-drop.component.html',
  styleUrls: ['./drag-and-drop.component.css']
})
export class DragAndDropComponent {

  /* De preferência criem classes para representar seus objetos */
  zoologicos = [
    { nome:'Zoo1', animais: ['Leão', 'Macaco'] },
    { nome:'Zoo2', animais: ['Tigre', 'Elefante'] }
  ];

  /* o resultado será uma lista com [Zoo1, Zoo2] */
  nomesDropList = [...this.zoologicos.map(zoo => zoo.nome)];

  /* 
   * Esta função é padrão, em qualquer exemplo no site do Angular Material 
   * você irá encontrá-la implementada deste modo. 
   * Pelo menos até este momento :D! 
   */
  drop(event: CdkDragDrop<any[]>) {    
    if (event.previousContainer === event.container) {
      moveItemInArray(
        event.container.data, 
        event.previousIndex, 
        event.currentIndex
      );
    } else {
      transferArrayItem(
        event.previousContainer.data,
        event.container.data,
        event.previousIndex,
        event.currentIndex
      );
    }
  }
}

Nada de mais concordam? Entretanto, tive muita dificuldade para encontrar algo que me ajuda-se a fazê-lo quando precisei.

Obrigado por chegar até aqui! Fim😎

Last updated