Listas interativas com Angular — Drag and Drop

Kheronn K. Machado
3 min readMar 18, 2019

--

Na versão 7 do Angular é possível utilizar um aspecto muito interessante para efeitos de interação, o drag and drop. O famoso arrasta e solta.

Nesse artigo eu mostro como utilizar esse recurso, aplicado a uma lista com personagens de um jogo. Se preferir, você pode assitir o vídeo.

Requisitos

Criado o projeto, é necessário incluir as seguintes dependências. No terminal informe:

$ ng add @angular/material

Aceite a instalação da biblioteca hammerjs e esolha um tema de sua preferência.

Com isso já podemos abrir o módulo principal e definir no array de import o módulo DragDropModule.

Para esse exemplo eu vou utilizar o HttpClientModule para carregar os dados de um arquivo local.

// Outros imports omitidos'@angular/platform-browser/animations';
import { HttpClientModule } from '@angular/common/http';
import { DragDropModule } from '@angular/cdk/drag-drop';

@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule,
BrowserAnimationsModule,
HttpClientModule,
DragDropModule

],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }

Na pasta assets vamos criar um arquivo data.json, com o seguinte conteúdo:

[
{
“name”: “Scorpion”,
“image”: “https://i.pinimg.com/564x/c4/b2/65/c4b2659a04c7cb1f99c1b2ed738f73d2.jpg",
“fatality”: “X + L2 + UP”
},
{
“name”: “Subzero”,
“image”: “https://i.pinimg.com/564x/80/b5/45/80b5458dd048c3457ca54a903de3f7ba.jpg",
“fatality”: “Up + Down + Up + Kick medium”
},
{
“name”: “Kitana”,
“image”: “https://i.pinimg.com/originals/4f/cc/cd/4fcccdf78814311d77be47d233db1699.png",
“fatality”: “X + L2 + UP”
},
{
“name”: “Aang”,
“image”: “http://rehatron-alpha.eu/images/6321365424_essay-help-forum.png",
“fatality”: “ L2 + UP”
}
]

Desta forma, temos um array de objetos com as propriedades que representam nossos personagens.

Lógica do componente

Abrindo a classe app.component.ts, vamos definir uma interface para mapear o personagem com os campos name, image e fatality.

export interface Character {
name: string;
image: string;
fatality: string;
}

Após a assinatura da classe vamos definir dois arrays que representarão nossas listas.

No método construtor, fazemos a injeção do HttpClient e chamamos o método getMyList().

A implementação é basicamente um get, tipando o resultado para nossa interface <Character[ ]>, informando o caminho da fonte de dados “assets/data.json”.

Ficamos ouvindo a emissão de eventos no subscribe, passando a lista para o mylist.

A próxima função, drop é responsável por duas ações.

Alterar a ordem dos elementos, utilizando a função movieItemInArray e/ou, mudar o item, no caso os personagens, para outra lista. Para isso utilizamos a função transferArrayItem.

A implementação deve verificar antes, qual a origem (container) do item, através do comando:

if (event.previousContainer === event.container) {

Segue o código completo da classe.

Template do componente

Vamos codifcar o template. Edite o app.component.html e deixe assim:

As linhas 8 e 17 são os locais onde definimos o container, utilizando a diretiva cdkDropList. Ainda na linha 8 criamos um atributo #minha e atribuímos a diretiva. Com isso podemos apontar para qual lista podemos arrastar os personagens, utilizando o atributo [cdkDropListConnectedTo].

Definimos a fonte de dados com [cdkDropListData] e finalmente a função

(cdkDropListDropped)=”drop($event)”, responsável pela ações definidas anteriormente.

Na linha 14, realizamos a iteração da lista com o *ngFor. Importante aqui também declamos a diretiva cdkDrag, indicando o elemento que pode ser arrastado.

Note que a partir da linha 17, codificamos a outra lista, alterando o nome e a fonte.

No arquivo de estilos, codificamos duas animações para alterar a ordem e para soltar o personagem.

.cdk-drop-list-dragging .cdk-drag {transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);}.cdk-drag-animating {transition: transform 300ms cubic-bezier(0, 0, 0.2, 1);}.img-person {border-radius: 35%;width: 80px;}

Fácil né?

Link do projeto no Git.

Até +

--

--