Adotei o guia de estilo AngularJS de John Papa recentemente e tem funcionado muito bem para mim até agora. Uma de suas regras de que não gosto são as promessas de ativação do controlador :
function AvengersViewModel(dataService) {
var viewModel = this;
viewModel.avengers = [];
viewModel.save = save;
activate();
function activate() {
return dataService.getAvengers().then(function (data) {
viewModel.avengers = data;
return viewModel.avengers;
});
}
function save() {
// (...)
}
}
Gosto do fato de que o código de ativação está em sua própria função, mas invocá-lo imediatamente é praticamente o mesmo que ter lógica no construtor . Isso significa que, se você quiser fazer o teste de unidade do método, save
precisará verificar dataService.getAvengers
se o stub foi feito corretamente.
Eu queria expor activate
e receber uma chamada de outra pessoa em vez de AvengersViewModel
:
function AvengersViewModel(dataService) {
var viewModel = this;
// (...)
// Expose it
viewModel.activate = activate;
function activate() {
// (...)
}
// (...)
}
Mas quem poderia ser esse alguém?
A abordagem ingênua
Eu sabia ngInit
, mas também sabia que não deveria usá-lo. Isso não me impediu de tentar:
function avengers() {
return {
scope: {},
template: '<div ng-init="viewModel.activate()">The avengers directive</div>',
controller: 'AvengersViewModel',
controllerAs: 'viewModel'
};
}
Isso funcionou, mas não parecia certo.
Uma abordagem melhor
Eu me lembrei de ver alguém usando o require
para disponibilizar o controlador da própria diretiva como o quarto parâmetro da link
função. Aparentemente, você pode até omitir a require
propriedade por completo e terá acesso à instância do controlador da diretiva:
function avengers() {
return {
scope: {},
template: '<div>The avengers directive</div>',
controller: 'AvengersViewModel',
controllerAs: 'viewModel',
link: function (scope, element, attributes, viewModel) {
viewModel.activate();
}
};
}
Agora posso testar a unidade corretamente em meus modelos de visualização e ter os benefícios das Promessas de ativação do controlador . Impressionante!