在子控制器中获取父控制器,它们都使用'controller as vm'表示法

时间:2014-04-09 15:07:39

标签: angularjs angularjs-controller

父控制器设置为' parentCtrl为vm '和chield设置为' childCtrl为vmc '没有名字冲突,而且运作良好。

如何在子控制器中访问父控制器?

请注意' $ scope。$ parent'没用。

3 个答案:

答案 0 :(得分:2)

要使用'$ scope'表示法访问父控制器,只需使用'$ scope。$ parent'。

然而,'controller as vm'符号缺少一个细节,使其适用于某些行为:

“$范围。$父。的 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;
            }
        });
    }
]);

但是,更改父对象会对基本对象产生副作用,这可以在以下angular.js文档中理解。

JavaScript Prototypal Inheritance

示例:

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;
          };
        }
    ]);
})();

答案 1 :(得分:1)

相反,您要做的是在控制器之间设置事件处理。这是控制器之间通信的正确方法。

例如,在您的父控制器中,您可以设置:

$scope.$on('getParentInfo', function(event, dataFromChild) {
   $scope.$broadcast('provideParentInfo', $scope.parentData);
});

并且在您的子控制器中,您可以请求父数据:

$scope.$emit('getParentInfo', $scope.childData);

$scope.$on('provideParentInfo', function(event, parentData){
    // do something with parent data
});

您需要进一步研究何时使用/不使用$broadcast$emit以及在销毁范围时自动解除绑定侦听器的替代方法,例如$onRootScope

此外,根据控制器的层次结构,我发现当控制器加载 get 事件的情况下,$emit$broadcast数据对它有帮助在事件监听器是带有数据的控制器之前发送接收控制器。

答案 2 :(得分:0)

如果您想在父控制器和子控制器之间共享数据,我相信最好的方法是创建一些包含共享方法\ data的服务。至少你不会看到$scope符号(你试图避免)。你会得到像这样的东西:

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();
});