3

$emitAngularJS では、あるディレクティブがイベントベースの通信 ( 、$broadcastおよび$on) を使用して、isolate スコープを持つ別のディレクティブと通信するにはどうすればよいですか? 2 つのディレクティブを作成しました。isolate スコープが 2 番目のディレクティブから削除されると、最初のディレクティブは、emit を使用して 2 番目のディレクティブと正常に通信できます。ただし、isolate スコープを 2 番目に戻すと、通信が切断されます。

var app = angular.module('myApp', []);

app.directive("firstDir", function() {
  return {
    restrict: 'E',
    controller: function($scope) {
      $scope.set = function() {
        $scope.$emit('MY_NEW_SEARCH', $scope.searchQuery);
      }       
    },
    template: '<input type="text" ng-model="searchQuery"><button ng-click="set()">Change Value</button>'
  };  
});

app.directive("secondDir", function() {
  return {
    restrict : 'E',
    scope: {},
    controller : function($scope) {    
      var _that = $scope;
      $scope.$on('MY_NEW_SEARCH', function(e, data) {
        _that.data = data;
      });
      $scope.data = 'init value';   
    }
  };  
});

問題を説明するためにプランカーを作成しました。2 番目のディレクティブのディレクティブ定義オブジェクトの "scope" プロパティをコメント アウトすると、通信が機能することに気付くでしょう。最初のディレクティブの入力ボックスに文字列を入力し、最初のディレクティブのボタンを押すことができます。ディレクティブに渡され、文字列は 2 番目のディレクティブに伝達され、ビューに表示されます。(現状では、Isolate スコープの問題により、Plunker は壊れています。app.js ファイルの 19 行目を参照してください。)

http://plnkr.co/edit/AXUVX9zdJx1tApDhgH32

私の包括的な目標は次のとおりです。2 番目のディレクティブに isolate スコープを使用する理由は、スコープの内側と外側のスコープを分離するためです。(私のプロジェクトで使用されている実際の「2 番目のディレクティブ」は、このおもちゃの例よりもはるかに複雑です。これが必要な理由です。) AngularJS がディレクティブの内部スコープに外部スコープをマッピングするためのメカニズムを提供することを知っています。これらのメカニズムのいずれかが、イベントベースの通信のイベントのマッピングに役立つかどうかに興味があります。

答えが、イベントベースの通信では分離スコープが克服できないということであることが判明した場合、目標を達成しながら、私が説明したケースでディレクティブ間の通信を達成するための最良の方法は何ですか? ありがとうございました!

4

1 に答える 1

5

これは 2 つの問題から生じます。

1) この最初のものは、両方のディレクティブが HTML で同じレベルにあるため、$emitあるスコープから別のスコープへのイベントはできません (2 番目のディレクティブが分離されたスコープを持たない場合のように、それらが同じスコープを持っていない限り)。 .

$scope.$emit最初のディレクティブが 2 番目のディレクティブに接続するには、(スコープ階層で上に行く) を$scope.$root.$broadcast(ルート スコープからそのすべての子に下に行く) に置き換えるか、単に$scope.$broadcastこの最初のディレクティブ スコープが実際、ルートスコープです!

2) 2 番目の問題は、2 番目のディレクティブが分離されている場合、スコープのトランスクルージョンをそのまま処理しないため、DOM でより深く定義された HTML はそのディレクティブの分離スコープを共有しませんが、定義されていない上記のものdataです。

分離されたスコープを内部の HTML に伝播する方法は、link関数内で次のスニペットを使用することです。

link: function(scope, element, attrs, ctrl, transclude) {
  transclude(scope, function(clone) {
    element.append(clone);
  });
}

これは、両方の修正を加えた動作中の Plnker です。

http://plnkr.co/edit/I9Vmutal2gfqyLIU0iAe?p=preview

于 2015-05-07T23:18:42.233 に答える