I would like to understand why when using a ng-repeat
with a certain controller on the item of the repeat, the parent of that item and the grandfather of that item are the same controller. I was expecting the grandfather to be the parent of the parent controller, not the same controller.
Here the code to clarify this
HTML
<div ng-controller="MainController">
{{name}}
<div ng-controller="SecondController">
{{name}}
<ul>
<li ng-repeat="item in list" ng-controller="ItemController">
{{item.name}} {{$parent.name}} {{myDad}} {{myGrandpa}}
</li>
</ul>
<div ng-controller="ThirdController">
{{name}} {{$parent.name}} {{myDad}} {{myGrandpa}}
</div>
</div>
</div>
JS
angular.module('app', []);
angular.module('app')
.controller('MainController', function($scope) {
$scope.name = "MainController";
})
.controller('SecondController', function($scope) {
$scope.name = "SecondController";
$scope.list = [
{'name': 'aaa'}
];
})
.controller('ItemController', function($scope) {
$scope.name = "ItemController";
$scope.myDad = $scope.$parent.name;
$scope.myGrandpa = $scope.$parent.$parent.name;
})
.controller('ThirdController', function($scope) {
$scope.name = "ThirdController";
$scope.myDad = $scope.$parent.name;
$scope.myGrandpa = $scope.$parent.$parent.name;
});
Here a CodePen
In Angular, $scope inherits and not controllers.
Each controller created by ng-controller creates a new $scope (childScope) that inherits from the $scope it exists in. I think you might want to read this answer to understand how exactly $scope inherits (prototypical inheritance).
Please not that you don't have to use "$parent" in order to get the name of the parent $scope, for example if you would remove $scope.name from ItemController and would try to bind {{name}} your template will be compiled and linked and the value of {{name}} would be "SecondController" in your example.
Regarding the $broadcast, You should try to avoid using $rootScope.$broadcast as it will dispatch an event down to all of the $scopes in your application. I'm not sure what your use case is, but if you want to execute a method that is defined in your "MainController" for instance, you can just call it for example
angular.module('app', []);
angular.module('app')
.controller('MainController', function($scope) {
$scope.name = "MainController";
$scope.doSomething = function() {
console.log("Do it");
}
})
.controller('SecondController', function($scope) {
$scope.name = "SecondController";
$scope.list = [
{'name': 'aaa'}
];
})
.controller('ItemController', function($scope) {
$scope.name = "ItemController";
$scope.myDad = $scope.$parent.name;
$scope.myGrandpa = $scope.$parent.$parent.name;
$scope.clickItem = function() {
console.log("Item clicked");
$scope.doSomething(); // The method from "MainController" will be executed unless ItemController is isolated
}
})
.controller('ThirdController', function($scope) {
$scope.name = "ThirdController";
$scope.myDad = $scope.$parent.name;
$scope.myGrandpa = $scope.$parent.$parent.name;
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With