Eu tenho uma diretiva que tem seu próprio controlador. Veja o código abaixo:
var popdown = angular.module('xModules',[]);
popdown.directive('popdown', function () {
var PopdownController = function ($scope) {
this.scope = $scope;
}
PopdownController.prototype = {
show:function (message, type) {
this.scope.message = message;
this.scope.type = type;
},
hide:function () {
this.scope.message = '';
this.scope.type = '';
}
}
var linkFn = function (scope, lElement, attrs, controller) {
};
return {
controller: PopdownController,
link: linkFn,
replace: true,
templateUrl: './partials/modules/popdown.html'
}
});
Este é um sistema de notificação de erros / notificações / avisos. O que eu quero fazer é de outro controlador (não um diretivo) para chamar a funçãoshow
neste controlador. E, quando faço isso, também quero que minha função de link detecte que algumas propriedades foram alteradas e execute algumas animações.
Aqui está um código para exemplificar o que estou pedindo:
var app = angular.module('app', ['RestService']);
app.controller('IndexController', function($scope, RestService) {
var result = RestService.query();
if(result.error) {
popdown.notify(error.message, 'error');
}
});
Portanto, ao chamar show
no popdown
controlador de diretiva, a função de link também deve ser disparada e executar uma animação. Como eu poderia conseguir isso?
javascript
jquery
angularjs
angularjs-directive
user253530
fonte
fonte
popdown
diretiva na página - é apenas em um lugar onde todos os outros controladores devem ter acesso a ela, ou há vários popdowns em locais diferentes?popdown.show(...)
nãopopdown.notify(...)
é? Caso contrário, a função de notificação é um pouco confusa.popdown.notify
?.notifiy
método, quero dizerRespostas:
Esta é uma pergunta interessante, e comecei a pensar em como implementaria algo assim.
Eu inventei isso (violino) ;
Basicamente, em vez de tentar chamar uma diretiva de um controlador, criei um módulo para abrigar toda a lógica popdown:
Coloquei duas coisas no módulo, uma
factory
para a API, que pode ser injetada em qualquer lugar, edirective
outra para definir o comportamento do elemento popdown real:A fábrica apenas define um par de funções
success
eerror
e mantém o controle de um par de variáveis:A diretiva obtém a API injetada em seu controlador e observa a api em busca de alterações (estou usando o bootstrap css por conveniência):
Então eu defino um
app
módulo que depende dePopdown
:E o HTML se parece com:
Não tenho certeza se é completamente ideal, mas parecia uma maneira razoável de estabelecer a comunicação com uma diretiva popdown global.
Novamente, para referência, o violino .
fonte
success(msg)
no html, você chamariasucess(name, msg)
para selecionar a diretiva com o nome correto.Você também pode usar eventos para acionar o Popdown.
Aqui está um violino baseado na solução de satchmorun. Ele dispensa o PopdownAPI e o controlador de nível superior, em vez
$broadcast
dos eventos de 'sucesso' e 'erro' na cadeia de escopo:O módulo Popdown, então, registra funções de manipulador para esses eventos, por exemplo:
Isso funciona, pelo menos, e me parece uma solução bem dissociada. Vou deixar que outros interfiram se isso for considerado uma prática inadequada por algum motivo.
fonte
Você também pode expor o controlador da diretiva ao escopo pai, como o faz
ngForm
comname
attribute: http://docs.angularjs.org/api/ng.directive:ngFormAqui você pode encontrar um exemplo muito básico de como isso poderia ser alcançado http://plnkr.co/edit/Ps8OXrfpnePFvvdFgYJf?p=preview
Neste exemplo, tenho
myDirective
um controlador dedicado com$clear
método (uma espécie de API pública muito simples para a diretiva). Posso publicar este controlador no escopo pai e usar a chamada desse método fora da diretiva.fonte
$scope.$parent[alias]
porque, para mim, cheira como usar API angular interna. Mas ainda não consigo encontrar uma solução mais elegante para diretivas não singleton. Outras variantes, como eventos de transmissão ou definir objeto vazio no controlador pai para API de diretiva cheiram ainda mais.Eu tenho uma solução muito melhor.
aqui está minha diretiva, injetei na referência de objeto na diretiva e estendi isso adicionando a função invoke no código da diretiva.
Declarando a diretiva no HTML com um parâmetro:
meu controlador:
fonte