This issue with primitives can be easily avoided by following the "best practice" of always have a '.' in your ng-models – watch 3 minutes worth. Misko demonstrates the primitive binding issue with ng-switch.
Having a '.' in your models will ensure that prototypal inheritance is in play. So, use
<input type="text" ng-model="someObj.prop1"> rather than
<input type="text" ng-model="prop1">.
— AngularJS Wiki - What are the nuances of scope prototypal / prototypical inheritance?
The DEMO on PLNKR
$scope.obj
is working like a $rootScope
variable. Is it for prototypal inheritance?
Scopes are arranged in hierarchical structure which mimic the DOM structure of the application. Each AngularJS application has exactly one root scope, but may have any number of child scopes.
ng-app --> $rootScope
|- ng-controller --> $scope (container)
|- ng-view --> $scope (view)
By using: <input ng-model="obj.name" />
the ng-model
directive in the view controller uses prototypical inheritance to find $scope.obj
from outside the view. It can then get and set the name
property of that object.
For more information, see AngularJS Developer Guide - Scope Hierarchies
$rootScope
exists, but it can be used for evil
Scopes in AngularJS form a hierarchy, prototypically inheriting from a root scope at the top of the tree. Usually this can be ignored, since most views have a controller, and therefore a scope, of their own.
Occasionally there are pieces of data that you want to make global to the whole app. For these, you can inject $rootScope
and set values on it like any other scope. Since the scopes inherit from the root scope, these values will be available to the expressions attached to directives like ng-show
just like values on your local $scope
.
Of course, global state sucks and you should use $rootScope
sparingly, like you would (hopefully) use with global variables in any language. In particular, don't use it for code, only data. If you're tempted to put a function on $rootScope
, it's almost always better to put it in a service that can be injected where it's needed, and more easily tested.
Conversely, don't create a service whose only purpose in life is to store and return bits of data.
— AngularJS FAQ - $rootScope exists, but it can be used for evil