Listas interativas com Angular — Drag and Drop
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é?
Até +