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

Percorrer uma Json duas vezes com ng-repeat dentro de uma table

Eu tenho a minha controller:

angular.module("appLista").controller("ListaTelefonicaController", function ($scope, $http) {
            $scope.app = "Lista Telefonica";

            $scope.contatos = [];
            var carregarContatos = function (){
              $http.get("http://localhost:8080/Restful/provas/listarProvas")
              .success(function (data, status){
                  $scope.contatos = data;
              });  
            };

            $scope.operadoras = [
                {nome: "Oi", codigo: 14, categoria: "Celular"},
                {nome: "Claro", codigo: 15, categoria: "Celular"},
                {nome: "Vivo", codigo: 16, categoria: "Celular"},
                {nome: "Embratel", codigo: 17, categoria: "Fixo"},
            ];

            $scope.adicionarContato = function (contato) {
                $scope.contatos.push(angular.copy(contato));
                delete $scope.contato;
                $scope.contatoForm.$setPristine();
            };

            $scope.apagarContato = function(contatos){
              $scope.contatos =  contatos.filter(function(contato){
                   if(!contato.selecionado) return contato;                  
                });
            };  


            $scope.ordernarPor = function(campo){
                $scope.criterioDeOrdenacao = campo;
                $scope.direcaoDaOrdenacao = !$scope.direcaoDaOrdenacao;
            };

            carregarContatos();

        });

E na view eu quero popular uma tabela com os dados retornados do $scope.contatos que é um Json ({"usuario":[{"email":"tassi@gmail.com","idUsuario":"3","nome":"Tassiany","senha":"rse"},{"email":"tiagorrr.tr@gmail.com","idUsuario":"1","nome":"Tiago Penha","senha":"123"}]}), eu tentei fazer dois ng-repeat só que não deu certo.

--View

body ng-controller="ListaTelefonicaController">
    <div class="jumbotron">
        <div class="formulario">        
            <h3>{{app}}</h3>         
            <input class="form-control" type="text" ng-model="criterioDeBusca" placeholder="O que você esta buscando?">
            <table ng-show="contatos.length > 0" class="table">
                <tr>
                    <th></th>
                    <th><a href="" ng-click="ordernarPor('nome')">Nome</a></th>
                    <th>Telefone</th>
                    <th><a href="" ng-click="ordernarPor('operadora')">Operadora</a></th>
                    <th></th>
                    <th>Data</th>
                </tr>
                <tr ng-class="{'selecionado negrito': contato.selecionado}" ng-repeat="contato in contatos | filter: criterioDeBusca | orderBy: criterioDeOrdenacao:direcaoDaOrdenacao">
                    <td><input type="checkbox" ng-model="contato.selecionado"></td>
                    <td>{{contato.nome}}</td>
                    <td>{{contato.telefone}}</td>
                    <td>{{contato.operadora.nome}}</td>
                    <td><div style="width:20px; height:20px;" ng-style="{'background-color': contato.cor}"></div></td>
                    <td>{{contato.data | date:'dd/MM/yyyy'}}</td>
                </tr>                
            </table>
            <hr/>
            <form name="contatoForm">
                <input class="form-control" type="text" ng-model="contato.nome" name="nome" placeholder="Nome" ng-required="true" ng-minlength="10"/>
                <input class="form-control" type="text" ng-model="contato.telefone" name="telefone" placeholder="Telefone" ng-required="true" ng-pattern="/^\d{4,5}-\d{4}$/"/>
                <select class="form-control" ng-model="contato.operadora" ng-options="operadora.nome group by operadora.categoria for operadora in operadoras | orderBy: 'nome'">
                    <option value="">Selecione uma operadora</option>
                </select>
            </form>

            <div ng-show="contatoForm.nome.$dirty" ng-messages="contatoForm.nome.$error">
                <div ng-message=".required"   class="alert alert-danger">
                        Por favor, preencha o nome.
                </div>
                <div ng-message=".minlength"  class="alert alert-danger">
                       O campo nome deve ter no minimo 10 caracteres
                </div>           
            </div>
            <div ng-show="contatoForm.telefone.$error.required && contatoForm.telefone.$dirty" class="alert alert-danger">
                Por favor, preencha o campo telefone.
            </div>

            <div ng-show="contatoForm.telefone.$error.pattern" class="alert alert-danger">
                O campo telefone deve ter o formato DDDDD-DDDD.
            </div>
            </div>
            <button class="btn btn-primary btn-block" ng-click="adicionarContato(contato)" ng-disabled="contatoForm.$invalid">Adicionar Contato</button>
            <button class="btn btn-danger btn-block" ng-click="apagarContato(contatos)" ng-if="isContatoSelecionado(contatos)">Apagar Contato</button>    
        </div>
    </div>   
</body>
</html>
10 respostas

Não entendi o que você quer. Baseado no que você escreveu, você diz que recebe um JSON que é um array. Sendo assim, um ng-repeat basta. Inclusive no seu código só vejo um ng-repeat sendo usado e não a tentativa de usar dois.

Não ficou claro para mim o que você quer usar o ng-repeat pela segunda vez.

Flavio, é que quando eu utilizo somente um ng-repeat a minha tabela não pega esses dados e imprime na tela, eu tenho que ficar passando um indice ex:

<table ng-show="contatos.length > 0" class="table">
                <tr>
                    <th></th>
                    <th><a href="" ng-click="ordernarPor('nome')">Nome</a></th>
                    <th>Telefone</th>
                    <th><a href="" ng-click="ordernarPor('operadora')">Operadora</a></th>
                    <th></th>
                    <th>Data</th>
                </tr>
                <tr ng-class="{'selecionado negrito': contato.selecionado}" ng-repeat="contato in contatos | filter: criterioDeBusca | orderBy: criterioDeOrdenacao:direcaoDaOrdenacao">
                    <td><input type="checkbox" ng-model="contato.selecionado"></td>
                    <td>{{contato[0].nome}}</td>
                    <td>{{contato[0].telefone}}</td>
                    <td>{{contato[0].operadora.nome}}</td>
                    <td><div style="width:20px; height:20px;" ng-style="{'background-color': contato.cor}"></div></td>
                    <td>{{contato.data | date:'dd/MM/yyyy'}}</td>
                </tr>

Por essa estrutura que você mandou

({"usuario":[{"email":"tassi@gmail.com","idUsuario":"3","nome":"Tassiany","senha":"rse"},{"email":"tiagorrr.tr@gmail.com","idUsuario":"1","nome":"Tiago Penha","senha":"123"}]})

é retornado um objeto que tem a propriedade usuario que tem um array dentro dela, sendo assim tenta fazer

ng-repeat="contato in contatos.usuario"

Eu estou tendo dificuldade em entender o que você deseja olhando seu código. Os modelos e as nomenclaturas não condizem como que eu espero do comportamento dele.

Vou dar um chute aqui do que eu entendi no seu código, dai você me corrige se eu estiver errado:

Você faz:

 <tr ng-class="{'selecionado negrito': contato.selecionado}" ng-repeat="contato in contatos | filter: criterioDeBusca | orderBy: criterioDeOrdenacao:direcaoDaOrdenacao">

Você esta iterando na propriedade contatos que é um array, certo? Mas cada item desse array é outro array, certo? Um contato não é um contato, mas vários contatos dentro de um array de contatos. . Isso que não entra na minha cabeça.

Ignorando esse fato, fica claro que você esta iterando em uma lista chamada contatos onde cada item é outra lista de alguma coisa. É essa lista que você quer iterar, certo?

Bom, se for....

<tr ng-class="{'selecionado negrito': contato.selecionado}" ng-repeat="contato in contatos | filter: criterioDeBusca | orderBy: criterioDeOrdenacao:direcaoDaOrdenacao">

    <td><input type="checkbox" ng-model="contato.selecionado"></td>

    <div ng-repeat="outraCoisa in contato">
        <td>{{outraCoisa.nome}}</td>
        <td>{{outraCoisa.telefone}}</td>
        <td>{{outraCoisa.operadora.nome}}</td>
    </div>
    <td><div style="width:20px; height:20px;" ng-style="{'background-color': contato.cor}"></div></td>
    <td>{{contato.data | date:'dd/MM/yyyy'}}</td>
</tr>

É isso que você precisa?

A solução do colega é ainda mais simples. No caso sua propriedade esta no singular, e isso confunde, porque ng-repeat só rola com array. E como não esta no plural... não fica evidente que é um array.

Foi desmarcada a solução. No caso, se alguma das respostas respondem ao seu problema. Peço que marque novamente.

Tiago, quando dominar o lance ng-repeat neste problema que deseja resolver, para que sua aplicação fique ainda melhor, dá uma olhada nos plurais quando for array.

Eu tenho te acompanhando aqui no fórum e criar uma aplicação do zero quando se esta começando é um avanço e tanto.

No final, você sabe que não basta ser ninja em programação, tem que ser cangaceiro e o que você puder lapidar no seu código, melhor para o projeto como um todo.

Oi Tiago, conseguiu?

solução!

Flavio, eu consegui popular a minha tabela fazendo dessa formar, tenho que melhora e muito todo o meu código.

<body ng-controller="ListaTelefonicaController">
    <div class="jumbotron">
        <div class="formulario">        
            <h3>{{app}}</h3> 
            <input class="form-control" type="text" ng-model="criterioDeBusca" placeholder="O que você esta buscando?">
            <table class="table">
                <tr>
                    <th></th>
                    <th><a href="" ng-click="ordernarPor('nome')">Nome</a></th>
                    <th>Telefone</th>
                    <th>Email</th>
                    <th>Twitter</th>
                </tr>
                <tr ng-class="{'selecionado negrito': contato.selecionado}" ng-repeat="contato in contatos.cliente | filter: criterioDeBusca | orderBy: criterioDeOrdenacao:direcaoDaOrdenacao">
                    <td><input type="checkbox" ng-model="contato.selecionado"></td>
                    <td>{{contato.nome}}</td>
                    <td>{{contato.telefone}}</td>
                    <td>{{contato.email}}</td>
                    <td>{{contato.twitter}}</td>
                </tr>                
            </table>
</body>

O código esta Ok, a estrutura, só a questão da nomenclatura mesmo para ficar ainda melhor. Por exemplo, seu contato.cliente como é um array, pode estar no plural, contato.clientes. Ai tem que trocar a propriedade de devolvida.

Fico contente de ter conseguido. Agora é continuar com o projeto!