AngularJS – Observe as mudanças em um serviço.

Eu tendo a dividir meus aplicativos em 3 grupos principais:

  • Módulo de aplicativo (controladores de aplicativo primários)
  • Diretivas de aplicativos
  • Serviços de aplicativos

Normalmente coloco muito da minha lógica em serviços que podem ser usados ​​dentro dos controladores e diretivas do aplicativo, mas só recentemente descobri que $watchpodem ser usados ​​em mais do que apenas o escopo do seu aplicativo!

Em uma diretiva na qual estava trabalhando, ngResourcesolicitei uma árvore de arquivos; a lógica para essa solicitação está dentro de um serviço que nomeei Tree.

Existem ações que devem fazer com que a árvore seja atualizada, mas como estava em um serviço, não estava conseguindo fazer com que funcionasse bem.

Insira $ watch

Eu gosto de assistir. Observar as alterações pode tornar bastante simples quando você precisa disparar ações com base nessas alterações sem turvar sua marcação com ng-changee ng-click.

Então, aqui está uma versão simplificada do meu aplicativo:

var App = app.module('ExampleApp', []);

/**
* Dummy Service

*/

App.service('Tree', function(){
this.rebuild = false;

this.Build = function(cb){
// resource request to get tree hierarcy
cb
(response);
};

return this;
});

App.directive('treeView', function(Tree){
return {
restrict: 'A',
link
: function(scope, elem, attrs){
scope
.data = []; // The directive template will loop this data

// Watch for changes in the service
scope
.$watch(function(){
return Tree.rebuild;
}, function(newVal, oldVal){
if(newVal) Tree.Build(function(response){ scope.data = response; Tree.rebuild = false; });
}
};

});

Portanto, em vez de observar uma chave no escopo, estou observando uma função que retorna os dados do serviço.

Por que isso é legal?

Agora, de QUALQUER LUGAR no meu aplicativo (digamos, um controlador de usuário, que realmente nem chega perto de tocar na diretiva), posso alternar Tree.rebuilde a diretiva será atualizada.

App.controller('UserCtrl', function($scope, Tree){
if($scope.user.newFile) Tree.rebuild = true;
})

Essa chamada simples agora atualizará a diretiva, e eu nem precisei recorrer a $rootScopeatribuições!