I created the second answer, to follow also the issue in this plunker, which @skip (OP) passed me as the example fo the issue.
Firstly There is an updated working version
of that plunker, which does what we need. There are the main changes:
The original state
def:
.state('home', {
url: '/',
views: {
'': { templateUrl: 'home.html' },
'A@home': {
templateUrl: 'a.html',
controller: 'MainCtrl'
},
'B@home': {
templateUrl: 'b.html',
controller: 'MainCtrl'
}
}
Was replaced with the RootCtrl
defintion:
.state('home', {
url: '/',
views: {
'': {
templateUrl: 'home.html',
controller: 'RootCtrl' // here we do use parent scoping
},
'A@home': {
templateUrl: 'a.html',
controller: 'MainCtrl'
},
'B@home': {
templateUrl: 'b.html',
controller: 'MainCtrl'
}
}
And this was one controller:
app.controller('MainCtrl', function($scope) {
var fruits = [{"name": "Apple"}, {"name": "Banana"}, {"name": "Carrot"}];
$scope.bar = $scope.bar || [];
$scope.foo = 2;
$scope.$watch('foo',function(value, oldValue){
$scope.bar = [];
getBar(fruits, value);
});
function getBar(fruits, howManyFruits) {
for(var i=0; i < $scope.foo; i++) {
$scope.bar.push(fruits[i]);
}
}
});
But now we do have two (Parent and child):
app.controller('RootCtrl', function($scope) {
$scope.bar = [];
})
app.controller('MainCtrl', function($scope) {
var fruits = [{"name": "Apple"}, {"name": "Banana"}, {"name": "Carrot"}];
//$scope.bar = $scope.bar || [];
$scope.foo = 2;
$scope.$watch('foo',function(value, oldValue){
$scope.bar.length = 0;
getBar(fruits, value);
});
function getBar(fruits, howManyFruits) {
for(var i=0; i < $scope.foo; i++) {
$scope.bar.push(fruits[i]);
}
}
});
Some important parts to mention
I. The least common denominator
We have to move the shared collection (array bar) into the parent. Why?
we have to move the shared reference to the least common denominator - to the parent scope
see
II. The Reference to array must be unchanged
we have to keep the reference to the Parent $scope.bar
unchanged!. This is essential. How to achieve that? see:
where instead of creating new reference, we clear the array, keeping the reference to it
// wrong
$scope.bar = [];
// good
$scope.bar.length = 0;
III. Controller can have multiple instances
Also, the fact that both views A and B had the same controller (same controller name in fact), definitely did not mean, that they were the same instance.
No, they were two different instances... not sharing anything. That is I guess, the most critical confusion. see
Controllers are special in that, unlike services, there can be many instances of them in the application. For example, there would be one instance for every ng-controller directive in the template.
Please, observe that all in the updated example