Is it proper to use $rootScope in a service?

3,717 views
Skip to first unread message

Jay Nathan

unread,
Dec 28, 2012, 10:00:36 PM12/28/12
to ang...@googlegroups.com
I have a service that I would like to $watch itself for any changes using the following: 

$rootScope.$watch('budgetService', function(newVal, oldVal){
        console.log('updating balances...');
        budgetService.updateBalances(); // updates some values in the object in response to changes made
        this.budgetUpdated(); // fires budget updated event: $rootScope.$broadcast('event.budgetUpdated');
}, true); // true = deep watch of object since budgetServices contains nested data

Syntactically and logically it works, but any idea what trouble I'm possibly getting myself into by injecting $rootScope into a service and using it in this way? My alternative is to $watch the object for changes in my controller and fire the method I need on the same object, but that spreads logic across controller and model which doesn't feel correct.

Any thoughts/guidance greatly appreciated. 

** And thanks to all who actively participate in this group. It has helped me greatly as I've come up to speed on AngularJS over the past few weeks.


Ivo Reis

unread,
Dec 29, 2012, 3:22:21 PM12/29/12
to ang...@googlegroups.com
Personally I don't use $watch this way. Although $watch can be used to check expressions (strings or functions). As stated in the documentation http://docs.angularjs.org/api/ng.$rootScope.Scope#$watch "It also means that watching complex options will have adverse memory and performance implications.". Also beware that the "rerun iteration limit is 10 to prevent an infinite loop deadlock."

Depending on what you are trying to accomplish, but it seems, IMO, that using a combination of a second service (that could be easily injected) with broadcast/emit features could tackle the case.

Jay Nathan

unread,
Dec 31, 2012, 3:28:37 PM12/31/12
to ang...@googlegroups.com
Thanks, I did read that in the docs and it does concern me, however, i have seen no performance issues thus far (nor iteration limits). I am using $broadcast to generate an event, however, how can I detect changes anywhere in the object? Clearly AngularJS is detecting the changes via $digest, so ideally I'd emit a generic event when Angular detects a change. 

Another idea I've had is to generate a one-way hash with the contents of the object and whenever a change is detected on that string value, broadcast my event. 

Thanks for your response. Happy New Year!

Ivo Reis

unread,
Dec 31, 2012, 5:46:58 PM12/31/12
to ang...@googlegroups.com
You can register an event listener on your scope / controller, something like this: http://plnkr.co/edit/72SdkLCSKjRpuDyHrWVD

Basically you broadcast and event on your $rootScope and register $on listeners where you want to handle the change.

Happy New Year! 

Jay Nathan

unread,
Jan 1, 2013, 9:43:43 AM1/1/13
to ang...@googlegroups.com
This makes sense. In order to use this method I'm going to have to make all changes to my data via methods so that I can $broadcast events when data is changed on the client. This takes a away some of the simplicity of angular's data binding, but is probably the best way to go. One thing I might try is using get/set methods and binding against those. 

Thanks!

Jay 
Reply all
Reply to author
Forward
0 new messages