Reputation: 19
Need help understanding how the code below is working.
After the first load the value displayed in the div element as well as the input element is 'Username', as expected.
However, why does the value in the first div element get modified when i modify the value in the input element considering that both the controllers have different and mutually exclusive scope variables??.
I believe this is connect withed with the rootScope but i am not sure how to connect the dots.
<html ng-app='myApp'>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.js"></script>
<script type="text/javascript">
var app = angular.module('myApp', []);
app.factory('userService',['$timeout', function($timeout){
var user = {}
$timeout(function(){
user.name = 'Username';
},5000);
return user;
}])
app.controller('c1', ['$scope', 'userService', function($scope, userService){
$scope.user = userService;
}])
app.controller('c2', ['$scope', 'userService', function($scope, userService){
$scope.user = userService;
}])
</script>
<body>
<div ng-controller="c1"><h1>{{user.name}}</h1></div>
<div ng-controller="c2"><input type="text" ng-model="user.name"/></div>
</body>
</html>
Upvotes: 1
Views: 68
Reputation: 5056
This is because you are referring the same factory object userService
in both the controllers.
Your factory is a singleton object i.e its initialized only once. So when you inject this as a dependency to your controllers you actually are sharing the same instance with all the controllers across your app.
Your scope variable $scope.user
is referring to the factory object
in both your controllers. And you have binded user.name
with ng-model
.
So for the first time it displays Username
as thats the value of $scope.user.name
or rather i should say userService.name
. So when the user types in the textbox this userService.name
what is it actually binded to as $scope.user
refers to userService
and hence it updates the userService.name
which is reflected in your controller c1
which is also referring to same instance of the factory object. And hence this behavior.
Below is a same demonstration that will help you understand more. As you can see i have created $scope.user
as a new object in controller c1
so it wont refer to the factory object now and hence the name wont get updated. But in controller c2
it will be updated.
<html ng-app='myApp'>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.js"></script>
<script type="text/javascript">
var app = angular.module('myApp', []);
app.factory('userService',['$timeout', function($timeout){
var user = {}
$timeout(function(){
user.name = 'Username';
},5000);
return user;
}])
app.controller('c1', ['$scope', 'userService','$timeout', function($scope, userService,$timeout){
$scope.user={};
$timeout(function(){
$scope.user.name = userService.name;
},5000);
}])
app.controller('c2', ['$scope', 'userService', function($scope, userService){
$scope.user = userService;
}])
</script>
<body>
<div ng-controller="c1"><h1>{{user.name}}</h1></div>
<div ng-controller="c2"><input type="text" ng-model="user.name"/>
<span>{{user.name}}</span>
</div>
</body>
</html>
Please read this for more info on services in angular
Hope it helps :)
Upvotes: 1
Reputation: 32145
However, why does the value in the first div element get modified when i modify the value in the input element?
Because you are just using two way binding here, it's sure you have two differents controllers with two differents scopes but these two scope variables $scope.user
refer to the same service value userService
so a change in one controller will affect the second one.
In other words binding the two variables to the same service is the same as using one conroller.
That's how Data binding works in Angular:
Data-binding in AngularJS apps is the automatic synchronization of data between the model and view components. The way that AngularJS implements data-binding lets you treat the model as the single-source-of-truth in your application. The view is a projection of the model at all times. When the model changes, the view reflects the change, and vice versa.
Upvotes: 0
Reputation: 11388
In angularJS, services are singleton.
And as fas as you never update the reference of your user, you are always working with the same object.
This service shared by multiple components is a common way to share data.
Upvotes: 2