I have the following MainController:
function MainController($scope, DataService) {
$scope.model = {
data: null
}
$scope.init = function () {
DataService.GetById(2)
.success(function (data, status, headers, config) {
$scope.model.data = data;
})
};
$scope.init();
}
I then have a child controller where I need to access the parent scope:
function ChildController($scope) {
$scope.model = {
data: null
}
$scope.init = function () {
#scope.model.data = $scope.$parent.model.data;
};
$scope.init();
}
I get an error saying $scope.$parent.model.data is null.
If I check the console $scope.$parent.model.data seems null but if I click it I see that it is not and it has the correct data ...
I believe the problem is I am defining the data in ChildController before it has been defined in the MainController due to DataService.GetById which queries the database ...
Am I right?
How can I solve this?
答案 0 :(得分:2)
You are right: the problem you have, is that your parent controller populates "data" inside a promise.
To understand what a promise is, you can check this : https://docs.angularjs.org/api/ng/service/$q
When your child controller is run, the promise will certainly not have returned yet.
The first way to handle that is adding a watch :
function ChildController($scope) {
$scope.model = {
data: null
}
$scope.init = function () {
//$scope.model.data = $scope.$parent.model.data;
var watchRemover = $scope.$watch('$parent.model.data', function(newVal, oldVal){
if (newVal !== oldVal && newVal !== null){
$scope.model.data = $scope.$parent.model.data;
watchRemover();
}
})
};
$scope.init();
}
Another solution is to handle it with events :
Parent controller :
DataService.GetById(2)
.success(function (data, status, headers, config) {
$scope.model.data = data;
$scope.$broadcast("data loaded");
});
child controller :
$scope.$on("data loaded", function(){
$scope.model.data = $scope.$parent.model.data;
});
答案 1 :(得分:1)
While setting up watches or using broadcast/edit is fine, I think a simpler solution would be binding one level upper.
Change $scope.model.data = $scope.$parent.model.data;
to $scope.model= $scope.$parent.model;
In this bind whenever $scope.$parent.model.data
change, it will also be reflected in $scope.model.data
. Be careful the reverse is also true, though.
Edit: On second thought, this approach won't help OP if he's not handling null correctly in the child controller, or else the original code would have worked. My approach is useful when $scope.$parent.model.data
changes, it will be automatically available in child.