指令間の通信にはかなりの数の方法があるようです。ネストされたディレクティブがあるとします。内部のディレクティブは外部に何かを伝える必要があります(たとえば、ユーザーが選択したもの)。
<outer>
<inner></inner>
<inner></inner>
</outer>
これまでのところ、これを行うには5つの方法があります
require:
親ディレクティブinner
ディレクティブはouter
ディレクティブを必要とする場合があり、そのコントローラー上のいくつかのメソッドを公開できます。したがって、inner
定義では
require: '^outer',
link: function(scope, iElement, iAttrs, outerController) {
// This can be passed to ng-click in the template
$scope.chosen = function() {
outerController.chosen(something);
}
}
そしてouter
ディレクティブのコントローラで:
controller: function($scope) {
this.chosen = function(something) {
}
}
$emit
イベントinner
ディレクティブは$emit
イベントを$on
を介してouter
ディレクティブが応答できるイベントにすることができます。したがって、inner
ディレクティブのコントローラで:
controller: function($scope) {
$scope.chosen = function() {
$scope.$emit('inner::chosen', something);
}
}
outer
ディレクティブコントローラで:
controller: function($scope) {
$scope.$on('inner::chosen, function(e, data) {
}
}
&
を介して親スコープで式を実行しますアイテムは、親スコープの式にバインドして、適切なポイントで実行できます。 HTMLは次のようになります。
<outer>
<inner inner-choose="functionOnOuter(item)"></inner>
<inner inner-choose="functionOnOuter(item)"></inner>
</outer>
したがって、inner
コントローラには、呼び出すことができる「innerChoose」関数があります
scope: {
'innerChoose': '&'
},
controller: function() {
$scope.click = function() {
$scope.innerChoose({item:something});
}
}
(この場合)outer
ディレクティブのスコープで 'functionOnOuter'関数を呼び出します。
controller: function($scope) {
$scope.functionOnOuter = function(item) {
}
}
これらがネストされたコントローラーであることを考えると、スコープの継承が機能している可能性があり、分離されたスコープがない限り、内部ディレクティブはスコープチェーン内の任意の関数を呼び出すことができます)。したがって、inner
ディレクティブで:
// scope: anything but a hash {}
controller: function() {
$scope.click = function() {
$scope.functionOnOuter(something);
}
}
そしてouter
ディレクティブで:
controller: function($scope) {
$scope.functionOnOuter = function(item) {
}
}
両方のディレクティブにサービスを挿入できるため、同じオブジェクトに直接アクセスしたり、関数を呼び出してサービスに通知したり、通知を受けるように自分自身を登録したりすることもできます。これには、ディレクティブをネストする必要はありません。
質問:それぞれの潜在的な欠点と利点は何ですか?
ディレクティブの&
定義をAPIと見なしているため、私の好みは、主にディレクティブスコープでscope: {}
属性を定義することです。スコープ属性の定義を調べて、ディレクティブが適切に機能するために必要な情報を確認する方が、リンクされたイベントと$emit
のイベント、継承されたスコープ関数または注入されたコントローラー内で使用される関数を探すよりもはるかに簡単です。
私の意見:
サービスは、モジュール/ディレクティブ/コントローラー間で動作/データを共有するための推奨される方法です。ディレクティブは、ネストできるかどうかに関係なく分離されたものです。コントローラーはできる限りビューモデルであることに固執する必要があります。理想的には、ビジネスロジックがそこに到達してはなりません。
そう:
親スコープ関数にアクセスしてそれらを一緒に配線し始めると、それらを非常に強く結合し、アプリケーション全体が読み取り不能になり、コンポーネントが再利用できなくなるリスクがあると思います。サービスでその共有データまたは動作を分離すると、実行時に使用するサービスを決定する場合でも、異なるデータ/動作でディレクティブ全体を再利用できるという利点があります。これが依存性注入のすべてです。