163

callback分離スコープで指定された属性を使用するフォーム ディレクティブがあります。

scope: { callback: '&' }

これは の中にあるng-repeatので、渡す式にidはオブジェクトの がコールバック関数への引数として含まれます。

<directive ng-repeat = "item in stuff" callback = "callback(item.id)"/>

ディレクティブの処理が完了すると、$scope.callback()コントローラー関数から呼び出されます。ほとんどの場合、これで問題ありません。やりたいことはこれだけですが、別の引数を内部から追加したい場合もありdirectiveます。

$scope.callback(arg2)this:を許可する角度式はあり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]) );

しかし、私はそれが特にきちんとしているとは思わず、isolate スコープに余分なものを入れる必要があります。

より良い方法はありますか?

Plunker プレイグラウンドはこちら(コンソールを開いてください)。

4

5 に答える 5

220

@ lex82 のようにコールバックを宣言すると

callback = "callback(item.id, arg2)"

オブジェクト マップを使用してディレクティブ スコープでコールバック メソッドを呼び出すと、バインディングが正しく行われます。お気に入り

scope.callback({arg2:"some value"});

$parse を必要とせずに。私のフィドル(コンソールログ)を参照してくださいhttp://jsfiddle.net/k7czc/2/

更新:ドキュメントにこれの小さな例があります:

& または &attr - 親スコープのコンテキストで式を実行する方法を提供します。属性名が指定されていない場合、属性名はローカル名と同じであると見なされます。指定されたスコープのウィジェット定義: { localFn:'&myAttr' } の場合、分離スコープ プロパティ localFn は count = count + value 式の関数ラッパーを指します。分離されたスコープから式を介して親スコープにデータを渡すことが望ましい場合がよくあります。これは、ローカル変数名と値のマップを式ラッパー fn に渡すことで実現できます。たとえば、式が increment(amount) の場合、localFn を localFn({amount: 22}) として呼び出して金額の値を指定できます。

于 2013-11-10T13:58:18.940 に答える
59

他の回答に問題はありませんが、ディレクティブ属性で関数を渡すときに次の手法を使用します。

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 の Dan Wahlin による優れた記事から採用しました。

関数の呼び出しをより自然にし、プロジェクトで発生したネストの問題を解決するために、アンラップ手順を追加しました。

于 2014-12-04T17:42:23.963 に答える
47

ディレクティブ ( 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>

... wheremyFunctionはコントローラで定義されています。

ディレクティブのテンプレートでは、ソースでparam適切にバインドされ、 に設定されていることに注意してください。paramitem


ディレクティブのプロパティ内 (「内部」) から呼び出すにlinkは、非常によく似たアプローチを使用します。

...
directive.link = function(isolatedScope) {
    isolatedScope.boundFunction({param: "foo"});
};
...
return directive;
于 2015-05-30T06:09:16.403 に答える