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

Exercicio Bonus - Remover titulo da lista dinamicamente

Estive analisando o tópico https://cursos.alura.com.br/forum/topico-como-compartilhar-uma-propriedade-entre-a-diretiva-e-o-controller-21747

Nesse tópico que trata da exclusão do foto com consequente atualização da lista conforme exercício bônus é proposta uma solução para escutar o evento através do $rootScope.on mas neste caso não deveria ser $rootScope.$on(...) ao invés de $rootScope.on(...) (Sem o $)?

Recebo o evento disparado, porem a lista não esta sendo atualizada dinamicamente. Como poderia manipular o DOM dinamicamente neste caso?

Essa implementação deveria ser realizada no ddo.controller ou no ddo.link?

Segue abaixo minhas alterações:

Arquivo minhas-diretivas.js

//Omitido restante do arquivo
.directive('meusTitulos', function() {
    var ddo = {};
    ddo.restrict = 'E';
    ddo.template = '<ul><li ng-repeat="titulo in titulos">{{titulo}}</li></ul>';
    ddo.controller = function($rootScope, recursoFoto) {

        recursoFoto.query(function(fotos) {
            $rootScope.titulos = fotos.map(function(foto) {
                return foto.titulo;
            });
        });
        $rootScope.$on("fotoRemovida", function(foto) {
            $rootScope.titulos.splice($rootScope.titulos.indexOf(foto.titulo, 1));
        });
    };
    return ddo;
});

Arquivo fotos-controller.js

...
    $scope.remover = function(foto){

        recursoFoto.remove({fotoId: foto._id}, function(){
            var indiceFoto = $scope.fotos.indexOf(foto);
            $scope.fotos.splice(indiceFoto, 1);

            //Alteração AQUI - Usei o $emit para o evento chegar ao $rootScope
            $scope.$emit('fotoRemovida', foto);

            $scope.mensagem = 'Foto ' + foto.titulo + ' removida com sucesso!';
        }, function(erro){
            $scope.mensagem = 'Falha ao remover a foto ' + foto.titulo;
            console.log(erro);
        });

    };

});

Grato

2 respostas

Oi Fábio! Na diretiva, você precisará usar a a função link. Isso porque, no controller, não é uma boa prática acessar elementos do DOM, local destinado para as diretivas.

Nesse exercício, o componente foi criado isolado e não havia a intenção de realizar a comunicação entre eles. Mas é possível sim.

solução!
// FotosController

    $scope.remover = function(foto) {

        recursoFoto.delete({fotoId: foto._id}, function() {
            var indiceDaFoto = $scope.fotos.indexOf(foto);
            $scope.fotos.splice(indiceDaFoto, 1);
            $scope.mensagem = 'Foto ' + foto.titulo + ' removida com sucesso!';
            alert(foto);
            $scope.$emit('fotoRemovida', foto); // disparando o evento
        }, function(erro) {
            console.log(erro);
            $scope.mensagem = 'Não foi possível apagar a foto ' + foto.titulo;
        });
    };

Agora, na diretiva:

    .directive('meusTitulos', function() {
        var ddo = {};
        ddo.restrict = 'E';
        ddo.template = '<ul><li ng-repeat="titulo in titulos">{{titulo}}</li></ul>';
        ddo.controller = function($scope, recursoFoto) {
            recursoFoto.query(function(fotos) {
                $scope.titulos = fotos.map(function(foto) {
                    return foto.titulo;
                });    
            });

            $scope.$on('fotoRemovida', function(event, foto) {
                alert('titulo a remover: '  + foto.titulo)
                $scope.titulos = $scope.titulos.filter(function(titulo) {
                    return titulo !== foto.titulo;
                });
            })
        };
        return ddo;
    });

Veja que em nenhum momento precisei manipular o DOM. Só precisei saber como funciona a função filter basicona do javaScript para poder filtrar a lista de títulos.

Mas veja, como disse, esse exemplo não foi feito com esse intuito, isso porque guardei uma lista de títulos da foto. Para ficar bonito, eu teria que na diretiva guardar a lista de fotos e exibir o título apenas.

Sucesso e bom estudo meu aluno!