7

2 つのテンプレートを要素に挿入して操作しようとしています。

<div
  ic-first="foo"
  ic-second="bar"
  ic-third="baz"
  ic-fourth="qux"
>
</div>

icFirstは、テンプレートを介して空の div をその要素の子として挿入する必要があります。icSecondは、その要素の 2 番目の子として 2 番目の div (多数のコンテンツを含む) を挿入する必要があるため、結果の html は次のようになります。

<div
  ic-first="foo"  // priority: 100
  ic-second="bar" // priority: 50
  ic-third="baz"  // priority: 0
  ic-fourth="qux" // priority: 0
>
  <div id="foo"></div>
  <div> <!-- a bunch of stuff from the templateUrl --> </div>
</div>

icFirsticSecondの両方が、新しく作成されたコンテナーに他の要素を挿入します。

両方のディレクティブでディレクティブ テンプレート プロパティを指定すると、次のエラーが発生します。

エラー: 複数のディレクティブ [icFirst, icSecond] でテンプレートを要求しています: <div ic-first…</p>

transclude: true両方のディレクティブに追加すると、 icFirstは問題なく実行されますが、同じ要素の他のディレクティブは実行されません。を設定するtransclude: 'element'と、他のディレクティブは実行されます、最初の子 ( $scope.firstObj) が未定義であるというエラーが表示されます。

4 つのディレクティブはすべて、互いのスコープにアクセスする必要があるため、ほとんどの作業はそれらのコントローラーで行っています。

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

プル リクエスト#2433replace: falseで説明されているように、文書化された動作に一致するようにの動作を修正したことに注意してください。

コントローラーでインスタンス化$scope.firstObjして、linkFn に設定しようとしましたが (linkFn が実行されるまでにトランスクルージョンが完了していることを願っています)、同じ問題が発生します。first-child は実際にはコメントのようです。

4

1 に答える 1

2

このエラーのスローを説明できる唯一の理由は、AngularJS チームが不要な上書き/DOM 操作を回避しようとしていたことです。

実際の動作と文書化された動作を考慮すると、実際の動作はreplace: false実際には意図された動作であると思います。これが true の場合、複数のテンプレート/templateUrl を同じ要素で使用できるようにすると、後続のテンプレートが前のテンプレートを上書きします。

文書化された動作に一致するようにソースを既に変更しているため、簡単な修正†</sup> として、ソースを再度変更 ( /src/ng/compile.js:700assertNoDuplicate ) してチェック ( に対応) を削除しましたangular.js:4624。今、私は次の 2 つのオブジェクトを返し、それが機能し、マイナスの影響を見つけることができません。

// 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
};

†</sup> 永続化された場合、チェックはおそらく次のようになります
if (directive.templateUrl && directive.replace)
(また、directive.template についても同様です)。

于 2013-04-19T00:56:49.553 に答える