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

Adicionar um ícone indicando a ordem na coluna

Ainda não encontrei a solução para esse problema rsrs.

Seguinte eu quero colocar uma "setinha" indicando para o usuário se a ordem é crescente ou decrescente utilizando o Font Awesome mas to meio perdido sobre como implementar essa lógica :(

8 respostas

Você sabe implementar em um projeto comum, sem ser este do curso?

Bom, pela minha lógica eu poderia simplesmente adicionar uma classe com o .classList.add(), colocar a "setinha" em um :before/:after ou adicionar uma um elemento span na coluna que foi clicada.

Mas aqui que eu to travando como: passar essa informação no template da view?

Você precisará criar alguma variável de controle para saber a orientação e a partir dela adicionar programaticamente a classe na coluna. Sua view não sabe dessa informação, só sabe mudar a orientação, por isso a variável de controle.

Infelizmente desde ontem estou tentando uma solução e não consegui implementar :/

Poste o código que você tentou até agora para que eu e outros possamos analisar. Você só precisa estar ligado que em nenhum momento a aplicação guarda o estado de ordenação por coluna, ela apenas inverte a ordem.

    inverteOrdem() {

        this._negociacoes.reverse();
    }

Você precisará de uma variável de controle para saber se esta ascendente ou descendente e guardar esse estado em seu modelo. Dai, lá na sua view, quando for renderizá-la, levará em consideração essa informação.

solução!

Bom, para adiantar o seu lado, vou dar uma solução prova de conceito. É que não terei tempo de voltar nessa discussão por agora. Vamos lá.

Primeiro, alterando seu modelo para guardar a informação se esta ordenado ascendentemente ou descendentemente:

class ListaNegociacoes {

    constructor() {

       /// ESTADO NOVO!
        this._ascendente = true;
        this._negociacoes = [];
    }

    adiciona(negociacao) {

        this._negociacoes.push(negociacao);
    }

    get negociacoes() {

        return [].concat(this._negociacoes);
    }

    esvazia() {

        this._negociacoes = [];
    }

    get volumeTotal() {
       return this._negociacoes.reduce((total, n) => total + n.volume, 0.0);
    }

    ordena(criterio) {

        this._negociacoes.sort(criterio);        
    }

    inverteOrdem() {

       /// MUDA ESTADO AQUI
        this._ascendente = ! this._ascendente;
        this._negociacoes.reverse();
    }    

    isAscendente() {
        return this._ascendente;
    }
}

Duas mudanças notáveis. O inverteOrdem agora troca o valor de this._ascendente a cada chamada. É basição mesmo, tipo, o valor variável true é ascendente e falseé descendente.

Agora, no template você pode consultar o estados do componente para indicar se esta ordenado ascendentemente ou descendentemente:

No caso, para demonstrar o resultado, coloquei um título acima da tabela:

class NegociacoesView extends View {

    constructor(elemento) {

        super(elemento);
    }

    template(model) {

        return `

        <h3 class="text-center">Ordenação ${model.isAscendente() ? 'Acendente' : 'Descendente'} </h3>

        <table class="table table-hover table-bordered">

            <thead>
                <tr>
                    <th onclick="negociacaoController.ordena('data')">DATA</th>
                    <th onclick="negociacaoController.ordena('quantidade')">QUANTIDADE</span></th>
                    <th onclick="negociacaoController.ordena('valor')">VALOR</th>
                    <th onclick="negociacaoController.ordena('volume')">VOLUME</th>
                </tr>
            </thead>

            <tbody>
                ${model.negociacoes.map(n => `

                    <tr>
                        <td>${DateHelper.dataParaTexto(n.data)}</td>
                        <td>${n.quantidade}</td>
                        <td>${n.valor}</td>
                        <td>${n.volume}</td>
                    </tr>

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

            <tfoot>
                <td colspan="3"></td>
                <td>
                    ${model.volumeTotal}
                </td>
            </tfoot>

        </table>
        `;
    }
}

Em suma, a informação da ordenação fica no modelo e você consulta no template. Nada o impede de aplicar um CSS condicional <td style="${model.isAcendente() ? 'classeDaSetaCima' : 'classeDaSetaBaixo'}"</td>.

Sucesso e bom estudo meu aluno!

Vlw demais Flávio! Desculpe a demora na resposta, mas acabei aperfeiçoando a solução que você postou, ficou um pouco verboso pelo o que eu quis fazer, mais ta valendo rsrs

class ListaNegociacoes {

    constructor() {

         /* Criando array para receber as negociações */
        this._negociacoes = [];

        /* Criando objeto literal para receber coluna e ordem da mesma */
        this._columnOrder = { column: '', order: '' };
    }

    // CODIGO OMITIDO

    /* Método para ordenar a lista de negociações de acordo com um critério */
    ordenaNegociacoesCrescente(coluna, order) {

      /* Ordenando a lista */
      this._negociacoes.sort(order);

      /* Armazenando informações de coluna e ordem */
      this._columnOrder = {
        column: coluna,
        order: 'ordem-crescente'
      };

    }

    /* Método para organizar a lista de forma decrescente  */
    ordenaNegociacoesDecrescente(coluna) {

      /* Ordenando a lista inversamente */
      this._negociacoes.reverse();

      /* Armazenando a coluna */
      this._columnOrder.column = coluna;

      /* Fazendo verificação da ordem */
      if(this._columnOrder.order == 'ordem-decrescente') {

        /* Alterando a ordem */
        this._columnOrder.order = 'ordem-crescente';

      } else {

        /* Alterando a ordem */
        this._columnOrder.order = 'ordem-decrescente';

      }

    }

    /* Método para retornar a ordem da coluna */
    columnOrder() {

      return this._columnOrder;

    }

    // CODIGO OMITIDO 

}

A diferença aqui foi que passei um objeto literal para armazenar a coluna e a ordem atual da mesma.

class NegociacoesView extends View {

    /* Método privado para construir o templete da tabela */
    template(model) {

      /* Recebendo informações de ordenação */
      let columnOrder = model.columnOrder();

        /* Montando e retornando o template */
        return `
            <table class="table table-hover table-bordered table-striped">
                <thead>
                    <tr>
                        <th ${(columnOrder.column == 'data') ? 'class="' + columnOrder.order + '"' : ''} onclick="negociacao.ordena('data')">DATA</th>
                        <th ${(columnOrder.column == 'quantidade') ? 'class="' + columnOrder.order + '"' : ''} onclick="negociacao.ordena('quantidade')">QUANTIDADE</th>
                        <th ${(columnOrder.column == 'valor') ? 'class="' + columnOrder.order + '"' : ''} onclick="negociacao.ordena('valor')">VALOR</th>
                        <th ${(columnOrder.column == 'volume') ? 'class="' + columnOrder.order + '"' : ''} onclick="negociacao.ordena('volume')">VOLUME</th>
                    </tr>
                </thead>

                <tbody>
                    ${model.negociacoes.map((negociacao) => {
                        return `
                            <tr>
                                <td>${DateHelper.dateToText(negociacao.data)}</td>
                                <td>${negociacao.quantidade}</td>
                                <td>${negociacao.valor}</td>
                                <td>${negociacao.volume}</td>
                            </tr>
                        `;
                    }).join('')}
                </tbody>

                <tfoot>
                    <tr>
                        <td colspan="3"><strong>TOTAL</strong></td>
                        <td>${model.volumeTotal}</td>
                    </tr>
                </tfoot>
            </table>
        `;



    }

}
class NegociacaoController {

    // CODIGO OMITIDO

    /* Método para ordenar as colunas */
    ordena(coluna) {

      if (this._listaNegociacoesOrdemAtual == coluna) {

        this._listaNegociacoes.ordenaNegociacoesDecrescente(coluna);

      } else {


        this._listaNegociacoes.ordenaNegociacoesCrescente(coluna, (a, b) => {
          return a[coluna] - b[coluna];
        });

      }

      this._listaNegociacoesOrdemAtual = coluna;

    }


}

Oi Rodrigo! Obrigado por compartilhar!

Sucesso e bom estudo, meu aluno!