从子控制器访问父控制器成员的优雅方式是什么?

时间:2016-08-17 18:15:37

标签: javascript angularjs

我在我的应用程序中使用controllerAs语法,我想从子控制器访问父控制器的功能,我知道这是通过注入$ scope可以实现的,但是考虑到Angular已经尝试过如此努力摆脱$来自代码的范围,我想知道在没有注入$ scope的情况下是否有更优雅的方法吗?

这是HTML的一个例子:

<div ng-controller="AppCtrl as app">
  <div ng-controller="ChildCtrl as child">
  </div>
</div>

相应的控制器:

angular.module('test').controller('AppCtrl', function () {
  var vm = this;
  vm.log = function() {
    console.log("Output");
  }
}  

angular.module('test').controller('ChildCtrl', function () {
  var vm = this;
  // Here I want to access parent's log() function
}  

我知道我可以注入$ scope然后通过$scope.app.log()访问日志功能,但是有一种更好的方式来访问日志而不注入$scope?

2 个答案:

答案 0 :(得分:2)

一种选择是使用Angular 1.5组件(docs)。

在子组件中看起来像这样:

.component('childComponent', {
  require: {
    parentCtrl: '^ parentCtrl'
  }
  controller: function() {
    this.parentCtrl.anyMethod(); //here we are accessing parent's controller properties
  }

  ...

});

答案 1 :(得分:1)

这个答案是在提出问题后大约6个月发布的,但我认为对其他访问者检查我建议的解决方案可能会有所帮助。

Angular控制器具有原型继承,这意味着子控制器可以访问父控制器的$scope对象。如果不是将您的属性和方法绑定到$scope,而是使用this关键字和controller as语法,则子项$scope将无法直接访问父级成员,但您仍然可以通过$scope.$parent访问它们。

也就是说,有两种可能的(干净且简单的)方法可以解决您的问题:

1)您可以将属性和方法绑定到父控制器的$scope对象,并通过任何子控制器中的$scope直接访问它们(如果需要,可以覆盖属性/方法) - 就像你经常Class)。 所以,如果你定义

$scope.log = function() { console.log("output") } 
在您的父控制器上,您的子控制器只需调用$scope.log()即可访问它。 Check this fiddle

2)或者,由于您使用this关键字和controller as语法将控制器绑定到视图,因此子项的$scope对象将无法直接访问父项的属性和方法,因为它们不是父控制器$scope的成员,而是this的成员,父控制器本身的实例。在这种情况下,您应该通过$scope.$parent访问父级。除此之外,“app”(您为“AppCtrl”创建的别名,因此该控制器本身的实例)将是$scope.$parent的属性。由于您将“log”方法定义为控制器本身的成员而不是其$scope对象,因此“log”是“app”的成员,您的子控制器可以访问父级的“log”方法,如下所示: $scope.$parent.app.log()Check this fiddle

以下是关于此主题的进一步阅读:https://github.com/angular/angular.js/wiki/Understanding-Scopes