Solucionado (ver solução)

Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

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!