Databinding with $rootScope

12,441 views
Skip to first unread message

Ben Sgroi

unread,
Oct 26, 2012, 12:52:06 PM10/26/12
to ang...@googlegroups.com
Hi - I'm wondering if I'm approaching the scope paradigm in the correct way.  I'm working on a page that uses two views, but shares data in between the controllers.  I'm storing the data model on $rootScope, so that it can be easily accessed from any of the controllers.  However, this makes two way databinding tricky.  Using the bracket notation works for read-only fields in the view (because of scope inheritance), but if I want to bind to, say, a text box, I can't just use ng-model="someProperty", because that's binding to the controller's scope, NOT the root scope.  I could use ng-model="$parent.someProperty" to bind directly to the root scope, but in reality, that will end up being something like ng-model="$parent.$parent.$parent... someProperty", which seems needlessly confusing and prone to page breakage.

Here's a pretty stripped down example of what I'm talking about: http://jsfiddle.net/bensgroi/tZZHb/1/

Does anyone have any feedback on this, or a better approach to maintaining a single data model?

Thanks.

Philip Holly

unread,
Oct 26, 2012, 2:18:25 PM10/26/12
to ang...@googlegroups.com
You can bind to an object on the parent scope instead of just properties. That way new local scope variables will not be created when written to.

So in your parent scope or root scope create an object that will store the variables you need.
For example:
$rootScope.sharedVars = {
  someProperty : "value1",
  otherProperty : "value 2"
};

<div ng-model="sharedVars.someProperty">

Philip

Ben Sgroi

unread,
Oct 26, 2012, 2:50:30 PM10/26/12
to ang...@googlegroups.com
Right.  The reason your example works is because the controller for that div inherits its scope from the $rootScope, and thus inherits sharedVars.  But if instead of a div, you used <input ng-model="sharedVars.someProperty", and then you typed "abc" in the text box, you'd be updating the value on the child scope only.  The value of someProperty on the root scope would remain "value 1", because you're not binding to the root scope but a new scope that inherited from the root scope.  This seems to be a problem I run into over and over with Angular, causing me to wonder if this is the right way to handle shared data.

Michael Bielski

unread,
Oct 26, 2012, 2:57:14 PM10/26/12
to ang...@googlegroups.com
What about setting a $watch on the local scope and having the watch function update the root scope? I've done that a few times where the page will not see large amounts of changes and it appears to work fine. I can see a page with large amounts of changes causing a performance hit, but I have no idea where that threshold would be.

Philip Holly

unread,
Oct 26, 2012, 3:02:06 PM10/26/12
to ang...@googlegroups.com
Did you try it? http://jsfiddle.net/tZZHb/4/

Ben Sgroi

unread,
Oct 26, 2012, 3:13:46 PM10/26/12
to ang...@googlegroups.com
Oops, I didn't.  I see that works.  It's strange that it works that way though.  I guess because the variable is an object and JS maintains a reference to it, whereas if the variable is a string, it simply copies the value during inheritance.

Thanks for your help!

Philip Holly

unread,
Oct 26, 2012, 3:33:44 PM10/26/12
to ang...@googlegroups.com
Yeah, it's the whole reference vs value thing I think. When you write to $scope.sharedVars.val1 it first gets the reference to $scope.sharedVars, which exists on the parent.

Another method to share data or events between controllers is to use $scope.$broadcast()$scope.$emit(), and $scope.$on(). See http://docs.angularjs.org/api/ng.$rootScope.Scope.

Philip
Reply all
Reply to author
Forward
0 new messages