[フレーム]
Last Updated: October 12, 2017
·
32.32K
· joseym

AngularJS - Watch for changes in a service.

I tend to break my applications up into 3 main groups:

  • App Module (primary app controllers)
  • App Directives
  • App Services

I usually put much of my logic into services that can be used within the app controllers and directives, but only recently discovered that $watch can be used on more than just your app scope!

In a directive I was working on I make a ngResource request to get a file tree; the logic for this request is inside a service I've named Tree.

There are actions that should cause the tree to refresh, but since it was in a service I was having trouble getting that to work well.

Enter $watch

I like watch. Watching for changes can make it pretty seamless when you need to fire actions based on those changes without muddying your markup with ng-change and ng-click.

So here's a dumbed down version of my application:

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; });
 }
 };

});

So instead of watching a key on the scope i'm watching a function that returns the service data.

Why is that cool?

Now, from ANYWHERE in my app (say a user controller, that really doesn't even come close to touching the directive) I can toggle Tree.rebuild and the directive will update.

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

That simple call will now update the directive, and I didn't even have to resort to $rootScope assignments!

AltStyle によって変換されたページ (->オリジナル) /