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

Ng-repeat não retorna dados :S

Bom dia, professor. Minha primeira dúvida aqui no fórum, então lá vai.

Estou criando uma aplicação mas o ng-repeat não está retornando os dados. Usando as aulas, eu fui montando o projeto de acordo com a necessidade então deixa eu ver se consigo explicar direitinho o que está acontecendo.

Seguindo o exemplo das aulas, criei uma diretiva chama "meu-painel.html", porém coloquei nele um breadcrumb.

<ol class="breadcrumb">             
     <li ng-repeat="item in itens">
          {{item.lista}}
     </li>    
</ol>

A página em específico, está sendo chamada por uma route.Provider conforme mostra o exemplo abaixo.

$routeProvider.when('/minha_pagina', {
    templateUrl : 'url/pagina.html',
    controller  : 'MeuController'
});

Este é o meu controller

app.controller('MeuController', function($scope) {
    $scope.itens = [
        { lista: 'teste' },
        { lista: 'segundo teste' }
    ];
    console.log($scope.itens);
});

O que eu estou achando estranho é que o console.log está retornando os objetos mas no browser não retorna nada.

Onde eu estou errando?

Obrigado pela ajuda :)

8 respostas

Acabei de descobrir um detalhe interessante. Se eu chamar a estrutura do breadcrumb no arquivo "pagina.html" funciona direitinho. O problema é se eu chamo ele na diretiva.

Existe uma maneira de corrigir isso?

Opa! Tem como postar o código da sua diretiva? Só vi o template dela, mas ficou faltando a declaração.

Aqui está.

angular.module('minhasDiretivas', [])
.directive('meuPainel', function() {
    var directive = {
        restrict: 'E',
        templateUrl: 'js/angular/directive/meu-painel.html',
        transclude: true,
        scope: {
            titulo: '@',
            section: '@'
        }
    };
    return directive;
});

Eu pensei em chamar o breadcrumb junto ao scope, mas não funcionou. :(

Desde já, obrigado pela atenção.

Aqui está o código html da diretiva

<div class="row">
    <div class="col-xs-6">
        <ol class="breadcrumb">            
            <li ng-repeat="item in itens">
                {{item.lista}}
            </li>
        </ol>
    </div>
    <div class="col-xs-6">
        <div class="alert alert-success">
            {{section}}
        </div>
    </div>
</div>

<div class="panel panel-default">
    <div class="panel-heading">
        <h1 class="panel-title">{{titulo}}</h1>
    </div>
    <div class="panel-body" ng-transclude>
    </div>
</div>

Hum, sua diretiva tem um escopo isolado, isso evita que ele bagunce o escopo pai. É por isso que ela não consegue acessar os dados do ng-repeat, porque eles não fazem parte do escopo da diretiva. Não adianta usar @ porque ele sempre passa para o escopo da diretiva uma string, e não um valor dinâmico. Como resolver? Ah, vem comigo que eu te mostro!!!!!

Primeira, coisa é dizer que sua diretiva depende de um dado externo que é uma referência, e não uma pura string:

angular.module('minhasDiretivas', [])
.directive('meuPainel', function() {
    var directive = {
        restrict: 'E',
        templateUrl: 'js/angular/directive/meu-painel.html',
        transclude: true,
        scope: {
            titulo: '@',
            section: '@',
            itens: '='
        }
    };
    return directive;
});

Veja que coloquei no escopo da diretiva o atributo itens, mas no lugar de usar @, usei =, para indicar que aquilo é uma comunicação bidirecional entre a diretiva e o escopo externo. A diretiva tem acesso de leitura e escrita daquele valor, e mais do que isso, quando ele mudar, a diretiva ficará sabendo. Se você tivesse usado @, não funcionaria, porque @ é sempre a copia do valor em string.

O template da sua diretiva continua do jeito que está, só precisamos mudar é o uso da sua diretiva em sua parcial:

<meu-painel titulo="Blablabla" itens="itens"></meu-painel>

Veja que a API da diretiva, no caso o atributo itens recebe como valor uma referência para a lista itens que está no escopo do controller. Agora essa lista passa a ser acessível dentro da diretiva e seu código vai funcionar.

Teste e me passe um feedback. Mande ver em AngularJS!

solução!

Só para você ficar ainda melhor em angular. Se você tem uma diretiva com escopo isolado, você pode usá-la onde quiser, sem interferir no escopo pai. Isso é fundamental para reutilização de componentes e essa é uma das grandes vantagens do Angularjs, pode isolar um pedaço de código, um componente, e reutilizá-lo em qualquer lugar da sua view. No caso de itens, a diretiva tem uma referência para a lista do controller, mas poderia ter sido qualquer controller, não importa, contanto que sua diretiva receba como referência os dados de que ela precisa.

Wow!!! Wooooowww!!!!

Funcionou perfeitamente, professor.

Muito obrigado mesmo pela explicação. Se eu continuar com essas aulas vou pedir pro chefe me passar pra Sênior :P

Forte abs.

Essa é a intenção :) ! Sucesso e bom estudo!