Get parent controller in child controller which all use 'controller as vm' notation

[亡魂溺海] 提交于 2020-02-02 04:48:06

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!