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)
15
respostas

Erro ao criar a diretiva minha-foto

Olá Professor,

No exercício para criar a diretiva minha-foto a aplicação parou de funcionar. Quando coloco a diretiva o principal.html fica repetindo.

index.html

<!DOCTYPE html>
<html lang="pt-br" ng-app="alurapic">
    <head>
        <meta charset="UTF-8">
        <base href="/">
        <meta name="viewport" content="width=device-width">
        <title>Alurapic</title>
        <link rel="stylesheet" href="css/bootstrap.min.css">
        <link rel="stylesheet" href="css/bootstrap-theme.min.css">
        <link rel="stylesheet" href="css/efeitos.css">
        <script src="js/lib/angular.min.js"></script>
        <script src="js/lib/angular-animate.min.js"></script>
        <script src="js/lib/angular-route.min.js"></script>
        <script src="js/main.js"></script>
        <script src="js/controllers/fotos-controller.js"></script>
        <script src="js/controllers/foto-controller.js"></script>
        <script src="js/directives/minhas-diretivas.js"></script>


    </head>
    <body>
        <div class="container">
            <ng-view></ng-view>
        </div> <!-- fim container -->        
    </body>
</html>

principal.html

<div>
    <h1 class="text-center jumbotron">Predial Primus</h1>
</div>

<div class="row">
    <div class="col-md-12">
    <form>
         <div class="input-group">
            <span class="input-group-btn">
                <a href="/fotos/new" class="btn btn-primary" type="button">
                    Nova foto
                </a>
            </span>
            <input class="form-control" placeholder="filtrar pelo título da foto" ng-model="filtro" ng-model-options="{ debounce: 500 }">
        </div> 
    </form>
    </div> <!-- fim col-md-12 -->
</div> <!-- fim row -->

<div class="row">
    <meu-painel class="col-md-2 painel-animado" ng-repeat="foto in fotos | filter: filtro" titulo="{{foto.titulo}}">
        <minha-foto url="{{foto.url}}" titulo="{{foto.titulo}}">
    </meu-painel>
</div> <!-- fim row -->

foto.html

<div class="page-header text-center">
    <h1>{{foto.titulo}}</h1>
</div>

<form novalidate name="formulario" class="row" ng-submit="submeter()">
    <div class="col-md-6">
        <div class="form-group">
            <label>Título</label>
            <input name="titulo" class="form-control" ng-model="foto.titulo" required ng-maxlength="20">
            <span class="form-control alert-danger" ng-show="formulario.$submitted && formulario.titulo.$error.required" >Título Obrigatório</span>
            <span class="form-control alert-danger" ng-show="formulario.titulo.$error.maxlength" >No máximo 20 caracteres</span>           
        </div>
        <div class="form-group">
            <label>URL</label>
            <input name="url" class="form-control" ng-model="foto.url" required>
            <span class="form-control alert-danger" ng-show="formulario.$submitted && formulario.url.$error.required" >Url Obrigatória</span>
        </div>
        <div class="form-group">
            <label>Descrição</label>
            <textarea name="descricao" class="form-control" ng-model="foto.descricao">
            </textarea>
        </div>

        <button type="submit" class="btn btn-primary">
            Salvar
        </button>
         <a href="/" class="btn btn-primary">Voltar</a>
        <hr>
    </div>
    <div class="col-md-6">
        <minha-foto url="{{foto.url}}" titulo="{{foto.titulo}}"></minha-foto>
    </div>
</form>

minhas-diretivas.js

angular.module('minhasDiretivas', [])
    .directive('meuPainel', function() {

        var ddo = {};

        ddo.restrict = "AE";
        ddo.transclude = true;


        ddo.scope = {
            titulo: '@'
        };

        ddo.templateUrl = 'js/directives/meu-painel.html';

        return ddo;
    })
    .directive('minhaFoto', function() {

        var ddo = {};

        ddo.restrict = "AE";

        ddo.scope = {
            titulo: '@',
            url: '@'
        };

        ddo.template = '<img class="img-responsive center-block" src="{{url}}" alt="{{titulo}}">';           

        return ddo;

    });
15 respostas

Olá Vitor. Principal fica repetindo? Como falar um pouco mais? Eu não consegui entender com clareza o problema.

O principal.html fica carregando várias vezes. Parece que se cria um loop no carregamento.

Você parece não ter fechado a diretiva assim:

<minha-foto url="{{foto.url}}" titulo="{{foto.titulo}}"></minha-foto>

Ela precisa abrir e fechar. Chuto que possa ser isso.

Realmente eu esqueci de fechar professor. Porém não é isso, ele continua repetindo o conteúdo do principal.html várias vezes na página.

Se eu abro o console de browser ele aparece várias vezes.

XHR finished loading: GET "http://localhost:3000/v1/fotos". XHR finished loading: GET "http://localhost:3000/v1/fotos". XHR finished loading: GET "http://localhost:3000/v1/fotos". XHR finished loading: GET "http://localhost:3000/v1/fotos". XHR finished loading: GET "http://localhost:3000/v1/fotos". XHR finished loading: GET "http://localhost:3000/v1/fotos". XHR finished loading: GET "http://localhost:3000/v1/fotos". XHR finished loading: GET "http://localhost:3000/v1/fotos". XHR finished loading: GET "http://localhost:3000/v1/fotos". XHR finished loading: GET "http://localhost:3000/v1/fotos". XHR finished loading: GET "http://localhost:3000/v1/fotos".

E fica carregando direto.

Então, cole o código restante do seu projeto, main.js, fotos-controller.js, foto-controller.js.

main.js

angular.module('alurapic', ['minhasDiretivas', 'ngAnimate', 'ngRoute'])
    .config( function ($routeProvider, $locationProvider) {

        $locationProvider.html5Mode(true);
        $routeProvider.when('/fotos', {

            templateUrl: 'partials/principal.html',
            controller: 'FotosController'
        });

        $routeProvider.when('/fotos/new', {
            templateUrl: 'partials/foto.html',
            controller: 'FotoController'
        });

        $routeProvider.otherwise({ redirectTo: '/fotos'});
    });

fotos-controller.js

angular.module('alurapic')
    .controller('FotosController', function ($scope, $http) {

        $scope.fotos = [];

        $scope.filtro = '';

        $http.get('v1/fotos')
        .then( function (retorno) {
            $scope.fotos = retorno.data;
        })
        .catch( function (error) {
            console.log(error);
        });
    });

foto-controller.js

angular.module('alurapic')
    .controller('FotoController', function ($scope) {

        $scope.foto = {};

        $scope.submeter = function () {
            console.log($scope.foto)
        }
    });

Testei seu código e tudo funcionou perfeito. Você só não mostrou o template do painel. Talvez ele seja o problema. Aliás, qual navegador você esta usando?

Só lembrando que para acessar a aplicação você precisa subir o servidor e acessá-la através de localhost:3000.

Estou usando o chrome. Quando eu tiro a diretiva minha-foto. Funciona normalmente.

Cole o código do template do painel.

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

Testei seu código é funcionou aqui. Não faço ideia de qual seja o problema. Compartilhe o projeto completo no github para que eu possa vê-lo como um todo. Mais de 2000 alunos passaram dessa parte sem problema algum. Vamos descobrir.

Olá professor, Criei um repositório no github.

https://github.com/vitorlsouza/angular

solução!

Descobri o problema.

O código que você compartilhou da sua diretiva não é o código que esta no github ( código compartilhado esta correto). E lá no github seu código não esta correto. É por isso que não consegui descobrir seu problema.

Veja como foi declarada a diretiva no seu github:

    .directive('minhaFoto', function () {

        var ddo = {};

        ddo.restrict = 'AE';

        ddo.scope = {
            titulo: '@',
            url: '@'
        }
                // erro aqui!
        ddo.templateUrl = '<img class="img-responsive center-block" src="{{url}}" alt="{{titulo}}">';

        return ddo;
    });

Você esta usando ddo.templateUrl quando na verdade o correto é template pois não esta apontado para um arquivo, e sim definindo um template corretamente.

Só corrigir. Aliás, sempre que compartilhar código compartilhe o que você esta usando em seu projeto para não confundir quem deseja te ajudar.

Sucesso e bom estudo!

Olá Professor,

Como eu fiquei tentando achar o problema acabei alterando o código e não percebi.

Resolveu o problema, obrigado pela ajuda!