it-swarm.com.de

Kann eine winklige Direktive Argumente an Funktionen in Ausdrücken übergeben, die in den Attributen der Direktive angegeben sind?

Ich habe eine Formaldirektive, die ein angegebenes callback-Attribut mit einem isolierten Bereich verwendet:

scope: { callback: '&' }

Es befindet sich in einem ng-repeat, so dass der übergebene Ausdruck die id des Objekts als Argument für die Rückruffunktion enthält:

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

Wenn ich mit der Direktive fertig bin, ruft sie $scope.callback() von ihrer Controller-Funktion auf. In den meisten Fällen ist dies in Ordnung, und ich möchte alles tun, aber manchmal möchte ich noch ein Argument aus der Variablen directive hinzufügen.

Gibt es einen Winkelausdruck, der dies zulässt: $scope.callback(arg2), wodurch callback mit arguments = [item.id, arg2] aufgerufen wird?

Wenn nicht, wie gehe ich am besten vor? 

Ich habe festgestellt, dass dies funktioniert:

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

Mit

scope { callback: '=', callbackArg: '=' }

und die Direktive aufrufen 

$scope.callback.apply(null, [$scope.callbackArg].concat([arg2, arg3]) );

Aber ich denke nicht, dass es besonders ordentlich ist, und man muss zusätzliche Dinge in den Isolatbereich legen.

Gibt es einen besseren Weg?

Plunker Spielplatz hier (Konsole offen lassen).

155
Ed Hinchliffe

Wenn du deinen Rückruf wie von @ Lex82 erwähnt deklarierst

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

Sie können die Rückmeldemethode im Geltungsbereich der Direktive mit der Objektzuordnung aufrufen, und die Bindung würde ordnungsgemäß ausgeführt. Mögen

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

ohne $ parse zu verlangen. Siehe meine Geige (Konsolenprotokoll) http://jsfiddle.net/k7czc/2/

Update: Es gibt ein kleines Beispiel in der Dokumentation :

& oder & attr - bietet die Möglichkeit, einen Ausdruck im Kontext von .__ auszuführen. der übergeordnete Bereich. Wenn kein attr-Name angegeben wird, dann der Attributname wird als identisch mit dem lokalen Namen angenommen. Gegebene und Widget-Definition des Bereichs: { localFn: '& meinAttr'}, dann zeigt die Isolateigenschaftseigenschaft localFn auf Ein Funktionswrapper für den Ausdruck count = count + value. Häufig Es ist wünschenswert, Daten aus dem isolierten Bereich über einen Ausdruck zu übergeben und für den übergeordneten Bereich kann dies durch Übergeben einer Karte von local .__ erfolgen. Variablennamen und -werte in den Ausdrucks-Wrapper fn. Beispiel: Wenn der Ausdruck increment (Betrag) ist, können wir den Betragswert Angeben, indem Sie localFn als localFn ({Anzahl: 22}) aufrufen.

210
Chandermani

Bei den anderen Antworten ist nichts falsch, aber ich benutze die folgende Technik, wenn Sie Funktionen in einem Direktionsattribut übergeben.

Lassen Sie die Klammer weg, wenn Sie die Direktive in Ihre HTML-Datei aufnehmen:

<my-directive callback="someFunction" />

Dann "entpacken" Sie die Funktion in der Verknüpfung oder dem Controller Ihrer Direktive. Hier ist ein Beispiel:

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
                });
            });
        }
    }
}]);    

Der Schritt "Entpacken" ermöglicht den Aufruf der Funktion mit einer natürlicheren Syntax. Sie stellt außerdem sicher, dass die Direktive ordnungsgemäß funktioniert, auch wenn sie in anderen Direktiven verschachtelt ist, die die Funktion übergeben können. Wenn Sie das Auspacken nicht durchgeführt haben, haben Sie ein Szenario wie dieses:

<outer-directive callback="someFunction" >
    <middle-directive callback="callback" >
        <inner-directive callback="callback" />
    </middle-directive>
</outer-directive>

Dann würden Sie in Ihrer inneren Anweisung so etwas enden: 

callback()()()(data); 

Was in anderen Verschachtelungsszenarien fehlschlagen würde.

Ich habe diese Technik aus einem ausgezeichneten Artikel von Dan Wahlin in http://weblogs.asp.net/dwahlin/creating-custom-angularjs-directives-part-3-isolate-scope-and-function-parameters angepasst.

Ich habe den Schritt zum Auspacken hinzugefügt, um das Aufrufen der Funktion natürlicher zu machen und um das Problem der Verschachtelung zu lösen, das mir in einem Projekt begegnet war. 

57
ItsCosmo

In Direktive (myDirective):

...
directive.scope = {  
    boundFunction: '&',
    model: '=',
};
...
return directive;

In der Vorlage Vorlage:

<div 
data-ng-repeat="item in model"  
data-ng-click='boundFunction({param: item})'>
{{item.myValue}}
</div>

In der Quelle:

<my-directive 
model='myData' 
bound-function='myFunction(param)'>
</my-directive>

... wobei myFunction im Controller definiert ist.

Beachten Sie, dass param in der Direktionsvorlage sauber an param in der Quelle gebunden ist und auf item gesetzt ist.


Um aus der link-Eigenschaft einer Direktive ("inside" davon) aufzurufen, verwenden Sie einen sehr ähnlichen Ansatz:

...
directive.link = function(isolatedScope) {
    isolatedScope.boundFunction({param: "foo"});
};
...
return directive;
38
Ben

Ja, es gibt einen besseren Weg: Sie können den $ parse-Dienst in Ihrer Direktive verwenden, um einen Ausdruck im Kontext des übergeordneten Bereichs auszuwerten, während Sie bestimmte Bezeichner im Ausdruck an Werte binden, die nur in Ihrer Direktive sichtbar sind:

$parse(attributes.callback)(scope.$parent, { arg2: yourSecondArgument });

Fügen Sie diese Zeile der Link-Funktion der Direktive hinzu, in der Sie auf die Attribute der Direktive zugreifen können.

Ihr Callback-Attribut kann dann wie callback = "callback(item.id, arg2)" festgelegt werden, da arg2 vom $ parse-Service in der Direktive an yourSecondArgument gebunden ist. Direktiven wie ng-click ermöglichen den Zugriff auf das Klickereignis über den $event-Bezeichner im Ausdruck, der mit genau diesem Mechanismus an die Direktive übergeben wird.

Beachten Sie, dass Sie mit dieser Lösung callback nicht zu einem Mitglied Ihres isolierten Bereichs machen müssen. 

15
lex82

Für mich hat folgendes gearbeitet:

in der Direktive erklären es so:

.directive('myDirective', function() {
    return {
        restrict: 'E',
        replace: true,
        scope: {
            myFunction: '=',
        },
        templateUrl: 'myDirective.html'
    };
})  

Verwenden Sie es in der Befehlsvorlage folgendermaßen:

<select ng-change="myFunction(selectedAmount)">

Und dann, wenn Sie die Direktive verwenden, übergeben Sie die Funktion folgendermaßen:

<data-my-directive
    data-my-function="setSelectedAmount">
</data-my-directive>

Sie übergeben die Funktion durch ihre Deklaration und sie wird aus der Direktive aufgerufen und die Parameter werden aufgefüllt.

0
jabko87