web-dev-qa-db-ja.com

AngularJS:ディレクティブスコープの=&@の違いは?

ディレクティブ内にisolate scopeを作成すると、outer scopeをマッピングできます内部スコープへ。属性にマップする6つの異なる方法を見てきました。

  1. = attr
  2. &attr
  3. @attr
  4. =
  5. @

これらのスコープマッピングオプションはそれぞれ何をしますか?

105
Shaun Luttin

これは混乱を招く可能性がありますが、願わくば、簡単な例がそれを明確にすることを願っています。まず、ビヘイビアからモデルバインディングを分離しましょう。

物事を結び付けるのに役立つフィドルは次のとおりです。 http://jsfiddle.net/jeremylikness/3pvte/

そして説明した...あなたのディレクティブが次のように見える場合:

<my-directive target="foo"/> 

次に、スコープにこれらの可能性があります。

{ target : '=' } 

これにより、scope.target(ディレクティブ)が$ scope.foo(外部スコープ)にバインドされます。これは、=が双方向バインディングであり、何も指定しない場合、内部スコープの名前がディレクティブの属性の名前に自動的に一致するためです。 scope.targetを変更すると、$ scope.fooが更新されます。

{ bar : '=target' } 

これにより、scope.barが$ scope.fooにバインドされます。これは、双方向バインディングを再度指定しますが、属性「target」に含まれるものが「bar」として内部スコープに表示されるように指示するためです。 scope.barを変更すると、$ scope.fooが更新されます。

{ target : '@' } 

@は「文字通り取得する」ことを意味するため、これによりscope.targetが「foo」に設定されます。 scope.targetの変更は、ディレクティブの外部には伝播しません。

{ bar : '@target' } 

@はtarget属性から値を取得するため、scope.barを「foo」に設定します。 scope.barへの変更は、ディレクティブの外部には伝播しません。

それでは、行動について話しましょう。外側のスコープにこれがあると仮定しましょう:

$scope.foo = function(parm1, parm2) { console.log(parm1 + ": " + parm2); } 

これにアクセスするにはいくつかの方法があります。 HTMLが次の場合:

<my-directive target='foo'>

それから

{ target : '=' } 

ディレクティブからscope.target(1,2)を呼び出すことができます。

同じこと、

{ bar : '=target' }

ディレクティブからscope.bar(1,2)を呼び出すことができます。

より一般的な方法は、これを動作として確立することです。技術的には、アンパサンドは親のコンテキストで式を評価します。それは重要です。だから私は持っている可能性があります:

<my-directive target="a+b" />

そして、親スコープに$ scope.a = 1および$ scope.b = 2がある場合、私のディレクティブで:

{ target: '&' } 

Scope.target()を呼び出すと、結果は3になります。これは重要です。バインディングは関数として内部スコープに公開されますが、ディレクティブは式にバインドできます。

これを行うより一般的な方法は次のとおりです。

<my-directive target="foo(val1,val2)"> 

次に使用できます:

{ target: '&' }

そして、ディレクティブから呼び出します:

scope.target({val1: 1, val2: 2}); 

これは、渡されたオブジェクトを取得し、プロパティを評価された式のパラメーターにマップしてから、動作を呼び出します。この場合は$ scope.foo(1,2)を呼び出します。

これを行うこともできます:

<my-directive target="foo(1, val)"/>

これにより、最初のパラメーターがリテラル1に、ディレクティブからロックされます。

{ bar: '&target' }

次に:

scope.bar(5) 

これは$ scope.foo(1,5)を呼び出します。

197
Jeremy Likness

概要

  1. @ attrは、一致するDOM属性の評価されたstring値にバインドします。
  2. = attrは、一致するDOM属性のスコープにバインドしますproperty
  3. &attrは、一致するDOM属性のスコープfunctionにバインドします。
  4. @
  5. =

ターゲットDOM属性の名前が分離スコープのプロパティ名と一致する場合、4、5、および6を使用します。これは、次の例の動作fiddleです。

HTML

<div ng-app='isolate'>
     <h3>Outer Scope</h3>

    <input type="text" ng-model="myModel" />
    <p>msg: {{ msg }}</p>
     <h3>Inner Scope</h3>

    <div id="inner">
        <div my-directive at="{{ myModel }}" equals="myModel" ampersand="msg=msg+'click'"></div>
    </div>
</div>

Javascript

angular.module('isolate', [])
    .directive('myDirective', function () {
    return {
        template:
            '<label>@attr</label><input value="{{ myAt }}" />' +
            '<label>@</label><input value="{{ at }}" />' +
            '<label>=attr</label><input ng-model="myEquals" />' +
            '<label>=</label><input ng-model="equals" />' +
            '<label>&attr</label><input type="button" ng-click="myAmpersand()" value="Btn" />' +
            '<label>&</label><input type="button" ng-click="ampersand()" value="Btn" />',
        scope: {
            myAt: '@at',
            myEquals: '=equals',
            myAmpersand: '&ampersand',
            at: '@',
            equals: '=',
            ampersand: '&'
        }
    };
});
44
Shaun Luttin