需要一个嵌套在父指令中的指令控制器,AngularJS

时间:2015-12-30 07:58:30

标签: angularjs angularjs-directive controller

我想知道是否有办法要求指令的控制器存在/嵌套在AngularJS中作为公共父的子指令。

指令结构

假设我的指令有以下结构:

<parent-directive>
    <ul>
        <li some-nested-directive ng-repeat="dir in directives"></li>
    </ul>
    <settings-menu></settings-menu>
</parent-directive>

指令定义

/* 
* some-nested-directive directive definition
*/
.directive('someNestedDirective', function(){
    // ...
    return {
       restrict: 'A',
       controller: someNestedDirectiveController
    };
});

/* 
* settings-menu directive definition
*/
.directive('settingsMenu', function(){
    return {
        restrict: 'AE',
        require: [], // how to require the nested-directive controller here?
        link: function(scope, iElement, attrs, ctrls){
            // ...
        }
    };
})

我已经检查了 this SO问题,该问题说明如何要求控制器存在于层次结构中同一行的指令。

但我的问题是关于 在指令层次结构中做同样的方法,这些指令不一定存在于同一行 。如果这是不可能的,那么它的正确解决方法是什么。任何帮助,将不胜感激。

修改

此外,是否可以使用require(或它们的组合)的任何前缀来实现相同的目标?

2 个答案:

答案 0 :(得分:2)

一种方法是使用parent指令作为在控制器之间传递引用的方法:

var mod = angular.module('test', []);

mod.directive('parent', function() {
  return {
    restrict: 'E',
    transclude: true,
    template: '<div>Parent <div ng-transclude=""></div></div>',
    controller: function ParentCtrl() {}
  }
});

mod.directive('dirA', function() {
  return {
    restrict: 'E',
    template: '<div>Dir A <input type="text" ng-model="name"></div>',
    require: ['dirA', '^^parent'],
    link: function(scope, element, attrs, ctrls) {
      //here we store this directive controller into parent directive controller instance
      ctrls[1].dirA = ctrls[0];
    },
    controller: function DirACtrl($scope) {
      $scope.name = 'Dir A Name';
      this.name = function() {
        return $scope.name;
      };
    }
  }
});

mod.directive('dirB', function() {
  return {
    restrict: 'E',
    template: '<div>Dir A <button ng-click="click()">Click</button></div>',
    require: ['dirB', '^^parent'],
    link: function(scope, element, attrs, ctrls) {
      //let's assign parent controller instance to this directive controller instance
      ctrls[0].parent = ctrls[1];
    },
    controller: function DirBCtrl($scope) {
      var ctrl = this;
      $scope.click = function() {
        //access dirA controller through parent
        alert(ctrl.parent.dirA.name());
      };
    }
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>


<div ng-app='test'>
  <parent>
    <dir-a></dir-a>
    <dir-b></dir-b>
  </parent>
</div>

使用上述方法时,将dirA控制器存储在parent控制器内的方式也是有意义的,即使用a getter property或仅显示{{1}的必需属性控制器。

答案 1 :(得分:0)

我对miensol的回复表示支持,我推荐这种做法,但在某些情况下你可能需要这样的东西;

<parent-directive>
<ul>
    <some-nested-directive id="snd1" ng-repeat="dir in directives"></some-nested-directive>
</ul>
<settings-menu some-nested-directive-id="snd1"></settings-menu>

您可以使用settings-menu;中的id访问some-nested-directive的范围;

$("#" + scope.someNestedDirectiveId).scope()

一旦我使用这种方法根据另一个独立下拉列表的选择级联下拉列表的值。