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

Deletar a linha criada com um botão seguindo os padrões do projeto

Boa tarde ,gostaria de deletar uma linha(tr) por um botão seguindo os padrões ensinados pela aula.

Implementação ProdutoController

class ProdutoController {
    constructor() {
            // VALORES EXTRAIDOS DOS FORMULARIOS
            let $ = document.querySelector.bind(document);
            this._inputNome = $('#nome');
            this._inputQuantidade = $('#quantidade');
            this._inputValor = $('#valor');
            //INSTANCIAR A LISTA
            this._listaProdutos = new ListaProdutos();
            //INSTANCIAR A VIEWS
            this._produtoView = new ProdutoView($('#produtoView'));
            this._produtoView.update(this._listaProdutos);
        }
        //EVENTOS
    adicionar(event) {
        event.preventDefault();
        this._listaProdutos.adiciona(this._criaProduto());
        this._produtoView.update(this._listaProdutos);
        this._limparFormulario();

    }
    remover(event) {
        //tentei utilizar este metodo para remover o elemento pai consequentemente todas tds dentro dela ao clicar em uma td desta tr
        var links = document.querySelectorAll('tr');
        for (var i = 0; i < links.length; i++) {
            links[i].addEventListener('click', removerPai);
        }

        function removerPai(e) {
            e.preventDefault();
            var li = this.parentNode;
            li.parentNode.removeChild(li);
        }

    }


    _criaProduto() {
        return new Produto(this._inputNome.value, this._inputQuantidade.value, this._inputValor.value);
    }
    _limparFormulario() {
        this._inputNome.value = '';
        this._inputQuantidade.value = 1;
        this._inputValor.value = 0;
        this._inputNome.focus();
    }

}

Implementação ProdutoView

class ProdutoView extends View {
    constructor(elemento) {
        super(elemento);
    }
    //ao abrir o console diz que a negociacaoController.remove(event) não é reconhecida isso pelo fato dela não ter sido instanciada aqui
    //entretanto se eu não criar um botão aqui eu não vou conseguir criar o evento aqui
    template(model) {
            return `
<table class="table table-hover table-bordered">
        <thead>
            <tr>
                <th>NOME</th>
                <th>QUANTIDADE</th>
                <th>VALOR</th>
                <th>BOTAO </th>
            </tr>
        </thead>

        <tbody>
            ${model.produtos.map(p => `

        <tr > 
            <td>${p.nome}</td>
            <td>${p.quantidade}</td>
            <td>${p.valor}</td>
            <td onclick="negociacaoController.remover(event)"><button class="btn btn-danger" type="button">Deletar</button></td>

        </tr>
        `)}
        </tbody>

        <tfoot>
        </tfoot>
    </table>

`;
    }


}
3 respostas
solução!

Opa Felipe, tudo bem? Algumas curiosidades:

Se o clique já dispara um evento identificando o td que foi clicado, por que adicionar um listener para todos os trs?

Se você colocou um botão pra definir a ação de deleção da linha, por que o evento é disparado pela td e não pelo botão?

Não fica um pouco contra intuitivo? Se você precisar adicionar um botão de edição, vai precisar mudar tudo. Não?

A dica então pra melhora e simplificar tudo é, move a ação de clique para o botão:

<td>
    <button class="btn btn-danger" type="button" onclick="negociacaoController.remover(event)">Deletar</button>
</td>

Ok, agora o botão é quem dispara a ação. Ela tá dentro de uma TD que está dentro da TR. precisamos subir dois níveis para encontrar o Pai. Considerando que o atributo target do objeto event é o botão, precisamos usar o parentNode duas vezes.

remover(event) {
    event.preventDefault();
    event.target.parentNode.parentNode.remove();
}

O que acha? Claro, você pode melhorar a legibilidade.

remover(event) {
    event.preventDefault();
    // sobre dois níveis: button > td > tr
    let linha = event.target.parentNode.parentNode;
    linha.remove();
}

Boaa,entendi perfeitamente(eu acho hehe),na verdade eu achei na internet aquilo como solução em um caso diferente e tentei adaptar, porem sem sucesso.Com teu código ficou claro que disparamos o evento em uma TD ,sendo assim é possível usar event.target para dizer opa seleciona este botão no caso está pegando aquele elemento e o parentNode indica pega esse elemento e seu pai com o .remove, remove todos esses dados da linha acredito que foi está tua ideia,só uma dúvida sobre "negociacaoController.remover(event)",nota-se que este método não foi instanciado na nossa view mas por ser carregada no nosso index e instanciamos NegociacaoController no index ele automaticamente carrega sem a necessidade de instancia na ViewNegociaçao,eu testei teu código no meu funcionou 100%,só perguntei pra solucionar a dúvida 100%,após isso colocarei como solucionada, obrigado pela ajuda ^^

Você não precisa instanciar a view por que ela já é instanciada diretamente no construtor do controller. Por isso. O restante é automático mesmo, visto que você já tem uma instância do controller, não precisa fazer novamente é só usar o método.