特定のcallback
属性を独立スコープで使用するフォームディレクティブがあります。
scope: { callback: '&' }
それはng-repeat
の中にあるので、私が渡す式はコールバック関数への引数としてオブジェクトのid
を含みます:
<directive ng-repeat = "item in stuff" callback = "callback(item.id)"/>
ディレクティブを使い終わったら、コントローラ関数から$scope.callback()
を呼び出します。ほとんどの場合、これで問題ありません。実行したいのはこれだけですが、directive
自体の中から別の引数を追加したいことがあります。
これを可能にする角度式がありますか:$scope.callback(arg2)
、その結果callback
はarguments = [item.id, arg2]
で呼び出されますか?
そうでない場合は、これを行うための最善の方法は何ですか?
私はこれがうまくいくことを発見しました:
<directive
ng-repeat = "item in stuff"
callback = "callback"
callback-arg="item.id"/>
あり
scope { callback: '=', callbackArg: '=' }
そしてディレクティブ呼び出し
$scope.callback.apply(null, [$scope.callbackArg].concat([arg2, arg3]) );
しかし、私はそれが特にきちんとしているとは思わないし、それは分離スコープに余分なものを入れることを含みます。
もっと良い方法はありますか?
ここでPlunkerの遊び場 (コンソールを開いてください)。
@ Lex82のようにコールバックを宣言した場合
callback = "callback(item.id, arg2)"
オブジェクトマップを使用してディレクティブスコープ内でコールバックメソッドを呼び出すことができ、それによってバインディングが正しく行われます。好き
scope.callback({arg2:"some value"});
$ parseを必要とせずに。私のフィドルを参照してください(コンソールログ) http://jsfiddle.net/k7czc/2/
更新: ドキュメント にこれの小さな例があります。
&or&attr - 親スコープのコンテキストで式を実行する方法を提供します。属性名が指定されていない場合、属性名はローカル名と同じであると見なされます。スコープのウィジェット定義が{localFn: '&myAttr'}であると仮定すると、スコーププロパティlocalFnを分離すると、count = count + value式の関数ラッパーがポイントされます。多くの場合、孤立したスコープから式を介して親スコープにデータを渡すことが望ましいです。これは、ローカル変数名と値のマップを式ラッパーfnに渡すことで実現できます。 たとえば、式がincrement(amount)の場合、localFnをlocalFn({amount:22})として呼び出すことで、amountの値を指定できます。
他の答えに問題はありませんが、ディレクティブ属性で関数を渡すときは、次の手法を使用します。
Htmlにディレクティブを含めるときは括弧を付けないでください。
<my-directive callback="someFunction" />
それからあなたのディレクティブのリンクまたはコントローラの中の関数を「アンラップ」します。ここに例があります:
app.directive("myDirective", function() {
return {
restrict: "E",
scope: {
callback: "&"
},
template: "<div ng-click='callback(data)'></div>", // call function this way...
link: function(scope, element, attrs) {
// unwrap the function
scope.callback = scope.callback();
scope.data = "data from somewhere";
element.bind("click",function() {
scope.$apply(function() {
callback(data); // ...or this way
});
});
}
}
}]);
「アンラッピング」ステップにより、より自然な構文を使用して関数を呼び出すことができます。また、関数を渡す可能性のある他のディレクティブ内にネストされている場合でも、そのディレクティブが正しく機能することを保証します。展開しなかった場合、次のようなシナリオがあるとします。
<outer-directive callback="someFunction" >
<middle-directive callback="callback" >
<inner-directive callback="callback" />
</middle-directive>
</outer-directive>
そうすると、内部指示文の中でこのようなものになってしまうでしょう。
callback()()()(data);
他の入れ子のシナリオでは失敗します。
私はダン・ワーリンによる素晴らしい記事からこの技術を採用しました http://weblogs.asp.net/dwahlin/creating-custom-angularjs-directives-part-3-isolate-scope-and-function-parameters
関数の呼び出しをより自然にし、プロジェクトで発生したネストの問題を解決するために、アンラップステップを追加しました。
指令(myDirective
)では、次のようになります。
...
directive.scope = {
boundFunction: '&',
model: '=',
};
...
return directive;
ディレクティブテンプレートの場合:
<div
data-ng-repeat="item in model"
data-ng-click='boundFunction({param: item})'>
{{item.myValue}}
</div>
出典:
<my-directive
model='myData'
bound-function='myFunction(param)'>
</my-directive>
... myFunction
はコントローラで定義されています。
ディレクティブテンプレートのparam
は、ソースのparam
にきちんとバインドされ、item
に設定されています。
ディレクティブのlink
プロパティ内(その「内部」)から呼び出すには、非常によく似た方法を使用します。
...
directive.link = function(isolatedScope) {
isolatedScope.boundFunction({param: "foo"});
};
...
return directive;
はい、もっと良い方法があります。式の中の特定の識別子を自分のディレクティブの中でしか見えない値にバインドしながら、親スコープのコンテキストで式を評価するには、ディレクティブで $ parse service を使用できます:
$parse(attributes.callback)(scope.$parent, { arg2: yourSecondArgument });
この行をディレクティブのリンク関数に追加して、ディレクティブの属性にアクセスできます。
Arg2はディレクティブ内の$ parseサービスによってyourSecondArgumentにバインドされているため、コールバック属性はcallback = "callback(item.id, arg2)"
のように設定できます。 ng-click
のようなディレクティブを使用すると、このメカニズムを使用して、ディレクティブに渡される式の中の$event
識別子を介してclickイベントにアクセスできます。
このソリューションでは、callback
を独立スコープのメンバーにする必要はありません。
私のために以下がうまくいった:
ディレクティブで次のように宣言します。
.directive('myDirective', function() {
return {
restrict: 'E',
replace: true,
scope: {
myFunction: '=',
},
templateUrl: 'myDirective.html'
};
})
ディレクティブテンプレートでは、次のように使用します。
<select ng-change="myFunction(selectedAmount)">
そして、ディレクティブを使用するときは、このように関数を渡します。
<data-my-directive
data-my-function="setSelectedAmount">
</data-my-directive>
あなたはその宣言によって関数を渡し、それはディレクティブから呼び出され、パラメータが移入されます。