1. ホーム
  2. angularjs

[解決済み] 新しい/分離されたスコープを求める複数のディレクティブ [ngController, ...] がある。

2022-02-14 07:08:56

質問

次のようなものがあります ( https://jsfiddle.net/hhgqup4f/5/ ):

<div parent parent-model="vm.model1" ng-controller="Controller as vm">
   Parent
</div>

そして、コントローラは

app.controller("Controller", Controller);

function Controller() {
  var vm = this;
  vm.model1 = "My Model 1";
  vm.model2 = "My Model 2";
}

そして、次のようなディレクティブを用意しています。

app.directive("parent", parent);

function parent() {

  var parent = {
    controller: ["$scope", controller],
    replace: false,
    restrict: "A",
    scope: {
      model: "="
    }
  };

  return parent;

  function controller($scope) { 
    console.log($scope.model);
  } 

}  

parent-model="vm.model1" で、コントローラのどのプロパティをディレクティブが使用するかを言おうとしています。しかし、ディレクティブの中で console.log($scope.model) を実行すると、エラーが発生します。

"Error: [$compile:multidir] Multiple directives [ngController, parent (module: app)] asking for new/isolated scope on: <div parent="" parent-model="vm.model1" ng-controller="Controller as vm">

これを解決するには?

どのように解決するのか?

エラーが発生しました ...

"Error: [$compile:multidir] Multiple directives [ngController, parent (module: app)] asking for new/isolated scope on: <div parent="" parent-model="vm.model1" ng-controller="Controller as vm">

...は、AngularJSが複数のディレクティブを許可していないため、非常にわかりやすい例です ( 同じ DOM レベルで を作成することができます。 アイソレート のスコープを使用します。

によると ドキュメント を防ぐために、この制限が設けられています。 衝突やサポートされていない設定 $scope オブジェクトを作成します。

通常、ディレクティブは分離された scope に向けての意図で コンポーネント化 または 再利用 DOMに付随する何らかのロジックやアクションの。

したがって、(少なくともAngularJSでは)2つの再利用可能なコンポーネントを合体させて複合効果を出すことができないのは理にかなっています。

解決方法

ディレクティブの使い方を以下のように変更します。 供給 には、その直属の親から必要なプロパティが渡されます ( であり、この場合は ngController ディレクティブ ).

<div ng-controller="Controller as vm">
  <div parent parent-model="vm.model1"></div>
</div>

同様に、ディレクティブの分離スコープに渡されたプロパティにアクセスするために、それらの 正規化 の形式で表示されます。

app.directive('parent', function(){
  return {
    scope: {
       parentModel: '='  // property passed from the parent scope
    },
    controller: function($scope){
       console.log($scope.parentModel); 
    }
  };
});

デモ


ディレクティブ・ツー・ディレクティブ・コミュニケーション

前述のように分離されたスコープを持つ2つ以上のディレクティブは、同じDOM要素で使用することはできません。しかし、ディレクティブのひとつが分離されたスコープを持つことは可能です。この場合、他のディレクティブは、必要であれば、通信することができます。 require イング というコントローラがあります。

<div dir-isolate dir-sibling></div>

...

.directive('dirIsolate', function(){
  return {
    scope: {},
    controller: function(){
      this.askSomething = function(){
         return 'Did you ask for something?';
      };
    }
  };
})
.directive('dirSibling', function(){
  return {
    require: 'dirIsolate', // here is the trick
    link: function(scope, iElement, attrs, dirSiblingCtrl){ // required controller passed to the link function as fourth argument
       console.log(dirSiblingCtrl.askSomething());
    }
  };
});