Angular - 在子指令的控制器中获取父指令的控制器(不是 link 函数)

Angular - get parent directive's controller in child directive's controller (not link function)

我知道如何在子指令的 link 函数中获取父 directive 控制器。
但是,我宁愿避免使用 link 函数(和 $scope 一起使用)并将我的所有代码都放在指令的 controller 函数下。

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

感谢任何帮助!

您可以将“$element”注入控制器并访问父控制器,如 -

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

这可能不是访问 'any' 父控制器的最透明方式,因为它需要指令的特定名称,而且它是 jqlite 而不是纯 Angular。

发现此线程有用 - How to access parent directive's controller by requiring it recursively?

编辑: 感谢@Dmitry 弄清楚 angular 不需要'.parent' 来获取控制器。更新代码 -

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

正确的模式是

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 将它们粘合在一起之前,您无法从子控制器访问父控制器。只要您在子方法中使用父控制器就可以了。

Controller 提供方法和初始属性来查看模型(并且它使用 controllerAs 更清洁),link 粘合这些东西,这就是指令的工作方式。

$scopelink 在 Angular 1.x 中都有其用途,即使在最新的社区发展中也是不可或缺的。无缘无故地驱逐他们是过分热心的,可能会导致糟糕的设计解决方案。代码中缺少 'link' 和 'scope' 字词无助于使应用程序更容易移植到 2.x。虽然现在学习 Angular 2 并为 1.x 养成正确的习惯。

See here or here

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