Javascript AngularJS:在同一元素上具有转义的多个指令

Javascript AngularJS:在同一元素上具有转义的多个指令,javascript,html,angularjs,angularjs-directive,Javascript,Html,Angularjs,Angularjs Directive,我正在尝试将两个模板插入到一个元素中并对其进行操作: <div ic-first="foo" ic-second="bar" ic-third="baz" ic-fourth="qux" > </div> 注意我已更正了replace:false的行为,以匹配记录的行为,如pull request中所述 我尝试在控制器中实例化$scope.firstObj,并在linkFn中设置它(希望转换在linkFn执行时完成),但我遇到了同样的问题。看起来第一个孩

我正在尝试将两个模板插入到一个元素中并对其进行操作:

<div
  ic-first="foo"
  ic-second="bar"
  ic-third="baz"
  ic-fourth="qux"
>
</div>
注意我已更正了
replace:false
的行为,以匹配记录的行为,如pull request中所述


我尝试在控制器中实例化
$scope.firstObj
,并在linkFn中设置它(希望转换在linkFn执行时完成),但我遇到了同样的问题。看起来第一个孩子实际上是一个注释。

我能想出的解释抛出此错误的唯一原因是AngularJS团队试图避免不必要的覆盖/DOM操作:

考虑到
replace:false
的实际行为与记录的行为相比,我认为实际行为实际上是预期的行为。如果这是真的,那么允许在同一元素上使用多个模板/TemplateURL将导致后续模板覆盖以前的模板

由于我已经修改了源代码以匹配记录的行为,作为一个快速修复†,我再次修改了源代码()以删除
assertNoDuplicate
检查(对应于
angular.js:4624
)。现在,我返回以下两个对象,它工作了,我找不到任何负面影响:

// directive icFirst
return {
  restrict: 'A',
  priority: 100,
  replace: false,
  template: '<div id="{{firstId}}"></div>',
  require: ["icFirst"],
  controller: Controller,
  link: postLink
};
// directive icSecond
return {
  restrict: 'A',
  require: ['icFirst'],
  replace: false,
  templateUrl: 'views/bar.html',
  priority: 50,
  controller: Controller,
  link: postLink
};
//指令icFirst
返回{
限制:“A”,
优先:100,
替换:false,
模板:“”,
要求:[“icFirst”],
控制器:控制器,
链接:postLink
};
//指令icSecond
返回{
限制:“A”,
要求:['icFirst'],
替换:false,
templateUrl:'views/bar.html',
优先:50,
控制器:控制器,
链接:postLink
};
†如果是永久性的,检查可能应为
if(directive.templateUrl&&directive.replace)


(与directive.template类似)

现在有一个更简单的方法。只需将
$$tlb:true
添加到您的指令中,它将绕过断言。@JonathanRowny
$$
表示
$$tlb
是API的“私有”部分,不应在API之外使用,因为开发人员可能会随时决定破坏它。
app.directive('icFirst', ['ic.config', function (icConfig) {
  return {
    restrict: 'A',
    priority: 100,
    template: '<div id="{{firstId}}"></div>',
    replace: false,
    transclude: 'element',
    controller: function icFirst($scope, $element, $attrs) {
      // …
      $scope.firstId = $scope.opts.fooId;
      $scope.firstElm = $element.children()[0];
      $scope.firstObj = {}; // this is used by the other 3 directives 
    },
    link: function(scope, elm, attrs) { … } // <- event binding
  }
);
app.directive('icSecond', ['ic.config', function (icConfig) {
  return {
    restrict: 'A',
    priority: 0,
    templateUrl: 'views/foo.html',
    replace: false,
    transclude: 'element',
    controller: function icSecond($scope, $element, $attrs) {
      // …
      $scope.secondElm = $element.children()[1];
      $scope.secondObj = new Bar( $scope.firstObj );
      // ^ is used by the remaining 2 directives & requires obj from icFirst
    },
    link: function(scope, elm, attrs) { … } // <- event binding
  }
);
// directive icFirst
return {
  restrict: 'A',
  priority: 100,
  replace: false,
  template: '<div id="{{firstId}}"></div>',
  require: ["icFirst"],
  controller: Controller,
  link: postLink
};
// directive icSecond
return {
  restrict: 'A',
  require: ['icFirst'],
  replace: false,
  templateUrl: 'views/bar.html',
  priority: 50,
  controller: Controller,
  link: postLink
};