问题
Parent controller set to 'parentCtrl as vm' and chield set to 'childCtrl as vmc' to be no name conflict and it works well.
How can I get access to parent controller in child controller?
Note that '$scope.$parent' did not work.
回答1:
To access the parent controller using the '$scope' notation just use '$scope.$parent'.
However the 'controller as vm' notation lacked a detail that makes it work with some behavior:
'$scope.$parent.vm'
app.controller('childCtrl', [
'$scope', function ($scope) {
var vmc = this;
// To protected access as vmc.parent
Object.defineProperty(vmc, 'parent', {
get: function () {
return $scope.$parent.vm;
}
});
}
]);
However changing the parent objects have side effects on primitive objects which may be understood in the following angular.js documentation.
JavaScript Prototypal Inheritance
Example:
Working example on JS Bin
<section class="parent"
data-ng-controller="parentCtrl as vm">
<input data-ng-model="vm.name">
<!-- have to change the prefix after the 'as' not to have conflict -->
<section class="child"
data-ng-controller="childCtrl as vmc">
<input data-ng-model="vm.name">
<!-- same results -->
<input data-ng-model="$parent.vm.name">
<!-- same results -->
<input data-ng-model="vmc.parent.name">
<!-- same results -->
<button data-ng-click="vmc.changeName()">Change name</button>
</section>
</section>
(function(){
var app = angular.module('app', []);
app.controller('parentCtrl', [
'$scope', function ($scope) {
var vm = this;
vm.name = 'Julia';
}
]);
app.controller('childCtrl', [
'$scope', function ($scope) {
var vmc = this;
// To protected access as vmc.parent
Object.defineProperty(vmc, 'parent', {
get: function () {
return $scope.$parent.vm;
}
});
vmc.changeName = function(){
vmc.parent.name = 'Other ' + vmc.parent.name;
};
}
]);
})();
回答2:
Instead what you want to do is set up event handling between controllers. That is the proper way to communicate between controllers.
For instance in your parent controller you might set:
$scope.$on('getParentInfo', function(event, dataFromChild) {
$scope.$broadcast('provideParentInfo', $scope.parentData);
});
and in your child controller you can request the parent data:
$scope.$emit('getParentInfo', $scope.childData);
$scope.$on('provideParentInfo', function(event, parentData){
// do something with parent data
});
You need to do some additional research on when to use/not to use $broadcast
and $emit
and alternative methods that handle automatically unbinding listeners when the scope is destroyed such as $onRootScope
.
Additionally, depending on the hierarchy of your controllers, i find it is helpful to $emit
or $broadcast
data when the controller loads in the case that the get event from the receiving controller is sent before the event listener is the controller with the data.
回答3:
If you want to share data between parent and child controller, I believe the best way to do it is to create some service which holds shared methods\data. At least you will not see $scope
notation (that you are trying to avoid). You'll get smth like this:
angular.module('app').service('SharedModel', function(){
var model = this;
var sharedData;
model.setData = function(data) {
sharedData = data;
};
model.getData = function() {
return sharedData;
};
});
angular.module('app').controller('ParentController', function(SharedModel){
SharedModel.setData("value");
});
angular.module('app').controller('ChildController', function(SharedModel){
var data = SharedModel.getData();
});
来源:https://stackoverflow.com/questions/22966720/get-parent-controller-in-child-controller-which-all-use-controller-as-vm-notat