在父指令中添加子指令指令

18

我有一个父指令,在链接函数中我想动态添加子指令。 子指令^需要parentDirective。 我能够添加任何HTML元素,但是一旦我尝试编译我的子指令,就会出现以下错误,它找不到所需的控制器。如果我手动添加子指令,它就可以完美地工作。

错误:

Error: [$compile:ctreq] Controller 'myInput', required by directive 'myKey', can't be found!

在添加元素后,我的模板应该长这样:
<myInput>
 <myKey></myKey> <-- added dynamically
 <myKey></myKey> <-- added dynamically
 <myKey></myKey> <-- added dynamically
  ....
</myInput>

myInput指令:

angular.module('myModule').directive('myInput', ['$log', '$templateCache', '$compile', function($log, $templateCache, $compile) {
  return {
    restrict: 'E',
    transclude: true,
    scope: {
      service: '=',            // expects a stimulus object provided by the tatoolStimulusService
      onkeydown: '&'           // method called on key press
    },
    controller: ['$scope', function($scope) {
      this.addKey = function(keyCode, value) {
        $scope.service.addInputKey(keyCode, { givenResponse: value });
      };
    }],
    link: function (scope, element, attr) {

      // add keys directives
      angular.forEach(scope.service.registeredKeyInputs, function(value, key) {
        var keyEl = angular.element(
          $compile('<myKey code="'+ key +'" response="'+ value.response +'"></myKey >')($rootScope));
        element.children(":first").append(keyEl);
      });

    },
    template: '<div ng-transclude></div>'
  };
}]);

myKey指令:

angular.module('myModule').directive('myKey', ['$log', '$sce', function($log, $sce) {
  return {
    restrict: 'E',
    scope: {},
    require: '^myInput',
    link: function (scope, element, attr, myCtrl) {
      myCtrl.addKey(attr.code, attr.response);

      // ...
    },
    template: '<div class="key"><span ng-bind-html="key"></span></div>'
  };
}]);
1个回答

25

将编译附加操作的顺序更改为附加编译:

var keyEl = angular.element('<myKey code="'+ key +'" response="'+ value.response +'"></myKey>');
element.append(keyEl);
$compile(keyEl)(scope);

显然,在这种情况下(查找父元素指令),编译的新元素已经在 DOM 中非常重要。

除非将 DOM 元素附加到 DOM,否则它没有父级(其 parentNode 属性为 null)。当 Angular 查找 ^myInput 时,它会沿着 DOM 树向上遍历,直到找到具有所需指令的节点。如果该元素尚未在 DOM 中,此搜索会立即失败,因为元素没有单个 parentNode。因此,您会收到错误信息。

此外,我建议将指令的名称从驼峰式更改为蛇形式:

<my-input>
    <my-key></my-key>
</my-input>

编译部分也将发生变化:

angular.element('<my-key code="'+ key +'" response="'+ value.response +'"></my-key >');

那个完美地运作了,甚至没有问题(尽管有关此的文档会更好)。我在帖子中只是使用虚拟名称,但你当然是对的,应该使用蛇形命名法。再次感谢。 - jimmy
1
我不了解文档,但这很容易理解。在 DOM 元素附加到 DOM 树之前,它没有父级(它的parentNode属性为null)。当 Angular 查找^myInput时,它会沿着 DOM 树向上遍历,直到找到一个具有所需指令的节点。在我们的情况下,它立即失败,因为该元素没有单个父节点。 - dfsq

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接