Orderby with ng-repeat nested in the Angularjs

Asked

Viewed 916 times

3

I need to order a list, which is in two ng-repeat, but I can only order within the group of the second ng-repeat and made a jsFiddle that shows my code:

https://jsfiddle.net/xxg4ajkk/2/

The order I want to work is as in the example below.

Ordered by name:

Alberto Alexandre - 2º Ciclo - prata
João Alfredo - 1º Ciclo - bronze
Maria Tomazio - 1º Ciclo - prata
Roxele Almondega - 2º Ciclo - ouro

Ordered per cycle:

João Alfredo - 1º Ciclo - bronze
Maria Tomazio - 1º Ciclo - prata
Alberto Alexandre - 2º Ciclo - prata
Roxele Almondega - 2º Ciclo - ouro

Ordered by plan:

Roxele Almondega - 2º Ciclo - ouro
Maria Tomazio - 1º Ciclo - prata
Alberto Alexandre - 2º Ciclo - prata
João Alfredo - 1º Ciclo - bronze
  • Did any of the answers work out?

  • I ended up asking to change the JSON without nesting per cycle. The two answers are excellent, and will help me a lot, thank you.

2 answers

2

When you need to sort a list of values and they are in different keys, you need to format the layout for a new one, then the initial proposal is to create a new one array with the key associados, example:

angular.module('app', [])
  .controller('minhaRede', ['$scope',
    function($scope) {
      $scope.sortBy = function(field) {
        $scope.predicate = field;
      }
      $scope.predicate = "nome_usuario"; // ordenação padrão
      $scope.minhaRede = {
        "id": "1",
        "type": "usuario-redes",
        "attributes": {
          "rede": [{
            "ciclo": 1,
            "associados": [{
              "nome_usuario": "João Alfredo",
              "plano": "bronze",
              "associado_situacao": "Ativo",
              "quem_indicou": "thaylon_lomonte",
              "created_at": "2017-05-17T18:03:03.810-03:00"
            }, {
              "nome_usuario": "Maria Tomazio",
              "plano": "prata",
              "associado_situacao": "Ativo",
              "quem_indicou": "thaylon_lomonte",
              "created_at": "2017-05-18T18:03:03.810-03:00"
            }]
          }, {
            "ciclo": 2,
            "associados": [{
              "nome_usuario": "Alberto Alexandre",
              "plano": "prata",
              "associado_situacao": "Ativo",
              "quem_indicou": "joao_alfredo",
              "created_at": "2017-05-21T18:03:03.810-03:00"
            }, {
              "nome_usuario": "Roxele Almondega",
              "plano": "ouro",
              "associado_situacao": "Ativo",
              "quem_indicou": "joao_alfredo",
              "created_at": "2017-05-20T18:03:03.810-03:00"
            }]
          }]
        }
      }
      //criação de uma lista formatada
      $scope.lista = function() {
        $associados = [];
        var rede = $scope.minhaRede.attributes.rede;
        angular.forEach(rede, function(item) {
          for (i = 0; i < item.associados.length; i++) {
            item.associados[i]['ciclo'] = item.ciclo + 'º Ciclo';
            item.associados[i]['seq'] =
              item.associados[i].plano == "ouro" ? 1 :
              (item.associados[i].plano == "prata" ? 2 : 3);
            $associados.push(item.associados[i]);
          }
        });
        return $associados;
      };
    }
  ])
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
  <div ng-controller="minhaRede">
    <div class="button-bar">
      <button ng-click="sortBy('nome_usuario')">Nome</button>
      <button ng-click="sortBy('seq')">Plano</button>
      <button ng-click="sortBy('ciclo')">Ciclo</button>
    </div>
    predicate: {{predicate}}
    <br><br>
    <div>
      <ion-item ng-repeat="associado in lista() | orderBy:predicate" style="border: 1px solid silver;">
        <b>{{associado.nome_usuario}}</b> - {{associado.ciclo}} - {{associado.plano}}<br>
      </ion-item>
    </div>
  </div>
</div>

2


You will need to create another view template due to being nested array. In the case of the plane, since the order is semantic, you will need to use a weight for each plane.

Concatenating the associates:

$scope.redeExibir = [].concat.apply([], $scope.minhaRede.attributes.rede.map((mapa) => {
    return mapa.associados.map((asso) => {
        asso.ciclo = mapa.ciclo;
        asso.plano = $scope.planos[asso.plano];
        return asso;
    })
}));

Filter to display planes according to weight:

app.filter('plano', function() {
    let planos = {
        'ouro': 1,
        'prata': 2,
        'bronze': 3
    };
    return function(input) {
        for (let prop in planos) {
            if (planos[prop] == input) return prop;
        }
    }
});

Upshot: https://jsfiddle.net/xxg4ajkk/3/

Browser other questions tagged

You are not signed in. Login or sign up in order to post.