Solucionado (ver solução)
Solucionado
(ver solução)
7
respostas

Excluir negociação individual com clique

Existe alguma forma de obter o índice de um elemento de um array com um clique? Tô tentando implementar uma forma de excluir o objeto da lista de negociações com um clique, mas não consigo acessar o índice ou o conteúdo do elemento clicado dinamicamente.

Se eu faço algo como isso no arquivo ListaNegociacoes :

retorne(index) {
    console.log(this._negociacoes[index]);
  }

e chamo isso no Controller:

retornarPeste() {
    this._listaNegociacoes.retorne(0);
  }

Eu consigo acessar o elemento do índice que eu passei como parâmetro, mas como fazer isso de forma dinamica clicando?

7 respostas

Fala ai Lucas, tudo bem? Você pode pegar o index da posição no array pelo próprio ngFor:

<li *ngFor="let item of items; index as i;">...</li>

Ai dentro da cada iteração, você pode enviar o i como parâmetro para a função que está sendo chamada:

<li *ngFor="let item of items; index as i;">
    <button (click)="remover(item, i)">Excluir</button>
</li>

E na função recebe tanto o item quanto seu index.

Espero ter ajudado.

Opa, uma dúvida, oque é essa ngFor? Nunca ouvi falar.

Fala Lucas, falha minha, por algum motivo achei que sua dúvida era sobre projetos em Angular, respondi tanta dúvida ontem que acabei confundindo, desconsidera minha primeira resposta.

Vamos para o seu problema novamente do zero:

Isso pode ser feito de N maneiras, tudo vai depender de como você está criando a tabela.

O que eu poderia recomendar nesse momento seria duas abordabens:

  1. Adicione um data attribute no sua tr informando o index dela, algo do tipo:
<tr data-index="1">...</tr>

Dai quando você clicar para deletar alguma negociação, você pega esse valor.

  1. Você pode tentar criar as tr's via JavaScript e adicionar um addEventListener para o botão delas:
negociacoes.forEach((negociacao, index) => {
    const tr = document.createElement('tr')
    const btn = document.createElement('button')

    btn.addEventListener('click', () => {
        // remover ela aqui...
    })

    // resto do código
})

Enfim, isso tem N maneiras de ser feito, como eu não conheço nada sobre seu projeto, sugeri essas dai, mas, tem muitos outros jeitos.

Se quiser compartilhar o projeto completo comigo, assim eu dou uma olhada e posso te dar outros caminhos que fazem mais sentido para seu cenário atual.

Pode compartilhar através do Github ou Google Drive (zipado).

Espero ter ajudado.

Bom, se você tiver tempo, e quiser dar uma olhada, tá aqui o repositório: https://github.com/tilucast/alura-frame.

De qualquer forma, obrigado pela disposição.

solução!

Fala ai Lucas, tudo bem? Fiz umas alterações aqui, primeiro na NegociacoesView na função template:

<tbody class="table-body">
                ${model.negociacoes
                  .map(
                      (n, i) => `
                    <tr>
                        <td>${DateHelper.dateToText(n.data)}</td>
                        <td>${n.quantidade}</td>
                        <td>${n.valor}</td>
                        <td>${n.volume}</td>
                        <td data-index="${i}" onclick="negociacaoController.remover(this)">X</td>
                    </tr>

                `
                  )
                  .join('')}
</tbody>

Modifiquei o tbody, basicamente adicione o index do array como segundo parâmetro do map e passei ele para um data attribute no td.

Também chamei a função remover do negociacaoController que recebe o próprio td.

Agora na classe NegociacaoController criei a função para remover:

remover(td) {
    const index = td.dataset.index;
    if (index >= 0) {
      this._listaNegociacoes.remove(index);
    }
  }

Ela pega o data attribute e verifique se o mesmo existe, se sim ela chama a função remove da ListaNegociacoes.

Na classe ListaNegociacoes adicionei uma função remove:

remove(index) {
    const novaLista = [...this._negociacoes];
    novaLista.splice(index, 1);
    this._negociacoes = novaLista
  }

Ela cria uma nova lista e remove um item dado uma posição específica do array.

E por último na NegociacaoController precisa fazer o bind dessa nova função remove:

this._listaNegociacoes = new Bind(
      new ListaNegociacoes(),
      new NegociacoesView(this._$('#negociacoesView')),
      'adicionaNegociacoes',
      'esvaziaNegociacoes',
      'ordenarLista',
      'inverterLista',
      'remove',
    );

Acho que foi isso, a ideia seria mais ou menos essa.

Claro que tem N jeitos de se implementar essa remoção, a que eu pensei aqui foi essa.

Espero ter ajudado.

Muito bom. Eu não conhecei os data attributes. Valeu fera.

Magina Lucas, sempre que precisar não deixe de criar suas dúvidas.

Os data attributes são para a gente "criar" atributos que não existem, para usar precisamos adicionar o prefixo data- seguido pela nossa necessidade.

Isso porque se a gente simplesmente colocar posicao ou meu-index o HTML tornaria-se inválido, porque esses atributos não existem.

Por isso criaram os data attributes para a gente "criar" os nossos mas mantendo o HTML válido.

Abraços e bons estudos.