2015-10-19 85 views
7

我知道如何在子指令的link函数中获取父级的directive控制器。
但是,我宁愿避免使用link函数(和$scope全部),并将所有代码都放在指令的controller函数下。Angular - 在子指令的控制器中获取父指令的控制器(不是链接功能)

angular.directive('parent', function(){ 
    return { 
     templateUrl: '/parent.html', 
     scope: true, 
     bindToController: true, 
     controllerAs: 'parentCtrl', 
     controller: function(){ 
      this.coolFunction = function(){ 
       console.log('cool'); 
      } 
     } 
    } 
}); 

angular.directive('child', function(){ 
    return { 
     templateUrl: '/child.html', 
     require: '^parent', 
     scope: true, 
     bindToController: true, 
     controllerAs: 'childCtrl', 
     controller: function() { 
      // I want to run coolFunction here. 
      // How do I do it? 
     } 
    } 
}); 

任何帮助表示赞赏!

+0

ü要避免使用链接?为什么? –

+0

我想用Angular2友好的方式编写代码。 – Dmitry

+0

@Dmitry坚持控制器和jqlite(正如答案正确表明的那样)会让你的代码对Angular 2产生敌意(这与友好性相反)。 – estus

回答

1

你可以注入“$元素”到控制器和接入类的父控制器 -

controller: ($element) -> 
    var parentCtrl = $element.parent().controller('parent'); 
    parentCtrl.coolFunction(); 
    //.......... 
    //.......... 

这可能不是访问“任意”父控制器的最透明的方式,因为它需要的具体名称该指令和它是jqlite而不是纯粹的Angular。

发现这个线索有用 - How to access parent directive's controller by requiring it recursively?

编辑:感谢@Dmitry搞清楚那个角度并不需要“.parent”得到控制。更新后的代码 -

controller: ($element) -> 
    var parentCtrl = $element.controller('parent'); 
    parentCtrl.coolFunction(); 
    //.......... 
+0

越来越接近所需的功能。我唯一不满意的是'$ element.parent()'部分,因为子代可能不是父代的直接子代,而是可能是两层深。我想我可以做一个递归检查属性“父”不知何故 – Dmitry

+0

@Dmitry - 我不喜欢使用'父'引用的粉丝。我希望有一个更优雅的方式。 – FrailWords

+0

我感谢你的帮助。它确实让我看着正确的方向。在检查[Angular的源代码](https://github.com/angular/angular.js/blob/master/src/ng/compile.js#L2005-L2042)之后,似乎调用'.parent'不是必要的。我实际上尝试过它,它没有'.parent'。更新您的答案,我会将其标记为已接受。 – Dmitry

4

为正确的模式将是

app.directive('child', function(){ 
    return { 
     templateUrl: '/child.html', 
     require: ['child', '^parent'], 
     scope: true, 
     bindToController: true, 
     controllerAs: 'childCtrl', 
     controller: function() { 
      this.coolFunction = function() { 
       this._parent.coolFunction(); 
      } 
     }, 
     link: function (scope, element, attrs, ctrls) { 
      var childCtrl = ctrls[0]; 
      var parentCtrl = ctrls[1]; 
      childCtrl._parent = parentCtrl; 
     } 
    } 
}); 

坏事是_parent被暴露在与范围controllerAs,但它很少会出现问题。

请注意,您将无权访问父控制器,直到link将它们粘合在一起。只要你在子方法中使用父控制器,这是很好的。

控制器提供了查看模型的方法和初始属性(它使用controllerAs更清晰),链接粘贴东西,这就是指令的工作方式。

$scopelink都有其在Angular 1.x中的用途,即使在最新的社区发展中也是不可或缺的。如果没有正当理由将它们排除在外,可能会导致糟糕的设计解决方案。代码中没有“链接”和“范围”字样将无助于使应用程序更易于移植到2.x.尽管现在学习Angular 2并为1.x开发适当的习惯。

0

See herehere

  1. var parentForm = $element.inheritedData('$formController') || ....
  2. var parentForm = $element.controller('form')
相关问题