AngularJS で、*独自のスコープを持つ*カスタム ディレクティブ内から親スコープにアクセスするにはどうすればよいでしょうか? 質問する

AngularJS で、*独自のスコープを持つ*カスタム ディレクティブ内から親スコープにアクセスするにはどうすればよいでしょうか? 質問する

ディレクティブ内で「親」スコープにアクセスする方法を探しています。スコープ、transclude、require、上からの変数 (またはスコープ自体) の受け渡しなど、あらゆる組み合わせです。私は全力を尽くしますが、完全にハッキーなものや保守不可能なものは避けたいと思っています。たとえば、$scopepreLink パラメータから を取得し、その$siblingスコープを反復処理して概念的な「親」を見つけることで、今すぐに実行できることはわかっています。

私が本当に望んでいるのは、親スコープで式を実行できるようにすることです$watch。それができれば、ここでやろうとしていることを実現できます。AngularJS - 変数を使用して部分をレンダリングする方法は?

重要な注意点は、ディレクティブは同じ親スコープ内で再利用可能である必要があることです。したがって、デフォルトの動作 (スコープ: false) は機能しません。ディレクティブのインスタンスごとに個別のスコープが必要であり、$watch親スコープ内に存在する変数が必要です。

コードサンプルは 1000 語に相当するため、次のようになります。

app.directive('watchingMyParentScope', function() {
    return {
        require: /* ? */,
        scope: /* ? */,
        transclude: /* ? */,
        controller: /* ? */,
        compile: function(el,attr,trans) {
            // Can I get the $parent from the transclusion function somehow?
            return {
                pre: function($s, $e, $a, parentControl) {
                    // Can I get the $parent from the parent controller?
                    // By setting this.$scope = $scope from within that controller?

                    // Can I get the $parent from the current $scope?

                    // Can I pass the $parent scope in as an attribute and define
                    // it as part of this directive's scope definition?

                    // What don't I understand about how directives work and
                    // how their scope is related to their parent?
                },
                post: function($s, $e, $a, parentControl) {
                    // Has my situation improved by the time the postLink is called?
                }
            }
        }
    };
});

ベストアンサー1

見るAngularJS のスコープ プロトタイプ / プロトタイプ継承のニュアンスは何ですか?

要約すると、ディレクティブが親 ( $parent) スコープにアクセスする方法は、ディレクティブが作成するスコープのタイプによって異なります。

  1. default ( scope: false) - ディレクティブは新しいスコープを作成しないため、ここでは継承はありません。ディレクティブのスコープは、親/コンテナと同じスコープです。リンク関数では、最初のパラメータ (通常はscope) を使用します。

  2. scope: true- ディレクティブは、親スコープからプロトタイプ継承する新しい子スコープを作成します。親スコープで定義されているプロパティは、ディレクティブで使用できますscope(プロトタイプ継承のため)。プリミティブ スコープ プロパティへの書き込みには注意してください。これにより、ディレクティブ スコープに新しいプロパティが作成されます (同じ名前の親スコープ プロパティが非表示/シャドウ化されます)。

  3. scope: { ... }- ディレクティブは新しい isolate/isolated スコープを作成します。親スコープをプロトタイプとして継承しません。 を使用して親スコープにアクセスすることはできます$parentが、通常は推奨されません。代わりに、、、表記を使用して、ディレクティブが使用される同じ要素の追加属性を介して、ディレクティブに必要な親スコープのプロパティ (および/または関数) を指定する必要が=あり@ます&

  4. transclude: true- ディレクティブは、親スコープからプロトタイプ的に継承する新しい「トランスクルードされた」子スコープを作成します。ディレクティブが分離スコープも作成する場合、トランスクルードされたスコープと分離スコープは兄弟になります。$parent各スコープのプロパティは同じ親スコープを参照します。Angular
    v1.3 の更新: ディレクティブが分離スコープも作成する場合、トランスクルードされたスコープは分離スコープの子になります。トランスクルードされたスコープと分離スコープは兄弟ではなくなりました。トランスクルードされたスコープ$parentのプロパティは分離スコープを参照するようになりました。

上記リンクには、4 種類の例と写真がすべて掲載されています。

ディレクティブのコンパイル関数のスコープにアクセスすることはできません(ここで説明されているように:https://github.com/angular/angular.js/wiki/Dev-Guide:-Understanding-Directives)。リンク関数でディレクティブのスコープにアクセスできます。

視聴中:

上記の 1. と 2. の場合: 通常は、ディレクティブに必要な親プロパティを属性で指定し、それを $watch します。

<div my-dir attr1="prop1"></div>
scope.$watch(attrs.attr1, function() { ... });

オブジェクトのプロパティを監視する場合は、$parse を使用する必要があります。

<div my-dir attr2="obj.prop2"></div>
var model = $parse(attrs.attr2);
scope.$watch(model, function() { ... });

@上記 3. (スコープの分離) については、 or表記法を使用してディレクティブ プロパティに付ける名前に注意してください=

<div my-dir attr3="{{prop3}}" attr4="obj.prop4"></div>
scope: {
  localName3: '@attr3',
  attr4:      '='  // here, using the same name as the attribute
},
link: function(scope, element, attrs) {
   scope.$watch('localName3', function() { ... });
   scope.$watch('attr4',      function() { ... });

おすすめ記事