Solucionado (ver solução)
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!