Wie übergebe ich mehrere Attribute an eine Angular.js-Attributanweisung?

116

Ich habe eine Attribut-Direktive wie folgt eingeschränkt:

 restrict: "A"

Ich muss zwei Attribute übergeben; eine Nummer und eine Funktion / einen Rückruf, auf die innerhalb der Direktive mit dem attrsObjekt zugegriffen wird.

Wenn die Direktive eine Element-Direktive wäre, "E"könnte ich mich darauf beschränken :

<example-directive example-number="99" example-function="exampleCallback()">

Aus Gründen, auf die ich nicht eingehen werde, muss die Direktive jedoch eine Attribut-Direktive sein.

Wie übergebe ich mehrere Attribute an eine Attributanweisung?

Ablenkung
quelle
Dies hängt von der Art des Bereichs ab, den Ihre Direktive erstellt (falls vorhanden). Folgende Optionen stehen zur Auswahl: kein neuer Bereich (Standard oder explizit mit scope: false), neuer Bereich (mit normaler prototypischer Vererbung, dh scope: true) und isolierter Bereich (dh scope: { ... }). Welche Art von Geltungsbereich schafft Ihre Richtlinie?
Mark Rajcok
1
@ MarkRajcok Es hat einen isolierten Bereich.
Undistraction

Antworten:

202

Die Direktive kann auf jedes Attribut zugreifen, das für dasselbe Element definiert ist, auch wenn die Direktive selbst nicht das Element ist.

Vorlage:

<div example-directive example-number="99" example-function="exampleCallback()"></div>

Richtlinie:

app.directive('exampleDirective ', function () {
    return {
        restrict: 'A',   // 'A' is the default, so you could remove this line
        scope: {
            callback : '&exampleFunction',
        },
        link: function (scope, element, attrs) {
            var num = scope.$eval(attrs.exampleNumber);
            console.log('number=',num);
            scope.callback();  // calls exampleCallback()
        }
    };
});

fiddle

Wenn der Wert des Attributs example-numberfest codiert wird, empfehle ich, ihn $evaleinmal zu verwenden und den Wert zu speichern. Die Variable numhat den richtigen Typ (eine Zahl).

Mark Rajcok
quelle
Ich habe das Beispiel-HTML bearbeitet, um Snake-Case zu verwenden. Ich weiß, dass ich es nicht als Element verwenden kann. Das ist der Punkt der Frage.
Undistraction
@Pedr, ja, tut mir leid, ich habe zu schnell über die Verwendung von Elementen gelesen. Ich habe die Antwort aktualisiert und festgestellt, dass Sie auch für die Attribute Snake-Case verwenden müssen.
Mark Rajcok
Kein Problem. Danke für deine Antwort. Ich habe die Attributnamen bearbeitet, um die Groß- und Kleinschreibung zu verwenden. Sie sind in Ordnung, wenn ich das aus Ihrer Antwort entferne, da es nur ein dummer Fehler von mir war und vom Punkt der eigentlichen Frage und Antwort ablenkt?
Undistraction
Ich verstehe das nicht - woher weiß die Direktive, dass sie genau dasselbe benennt, was in der Direktivenverwendung ("exampleCallback ()") in ihrem Geltungsbereich angegeben ist? ("callback: '& exampleCallback') Sollte der Bereich nicht" callback: "& exampleFunction" sein?
Blaster
1
@FredrikL, für mehrere Anweisungen auf dem gleichen Element, siehe stackoverflow.com/a/28735005/215945
Mark Rajcok
19

Sie machen es genauso wie mit einer Element-Direktive. Sie haben sie im attrs-Objekt. In meinem Beispiel sind sie über den Isolatbereich in beide Richtungen gebunden, aber das ist nicht erforderlich. Wenn Sie einen isolierten Bereich verwenden, können Sie mit scope.$eval(attrs.sample)oder einfach auf scope.sample auf die Attribute zugreifen. Abhängig von Ihrer Situation werden diese jedoch möglicherweise nicht beim Verknüpfen definiert.

app.directive('sample', function () {
    return {
        restrict: 'A',
        scope: {
            'sample' : '=',
            'another' : '='
        },
        link: function (scope, element, attrs) {
            console.log(attrs);
            scope.$watch('sample', function (newVal) {
                console.log('sample', newVal);
            });
            scope.$watch('another', function (newVal) {
                console.log('another', newVal);
            });
        }
    };
});

benutzt als:

<input type="text" ng-model="name" placeholder="Enter a name here">
<input type="text" ng-model="something" placeholder="Enter something here">
<div sample="name" another="something"></div>
Jonathan Rowny
quelle
9

Sie können ein Objekt als Attribut übergeben und wie folgt in die Direktive einlesen:

<div my-directive="{id:123,name:'teo',salary:1000,color:red}"></div>

app.directive('myDirective', function () {
    return {            
        link: function (scope, element, attrs) {
           //convert the attributes to object and get its properties
           var attributes = scope.$eval(attrs.myDirective);       
           console.log('id:'+attributes.id);
           console.log('id:'+attributes.name);
        }
    };
});
Theo Itzaris
quelle
Ist es möglich, einen booleschen Wert mit einem Objekt zu senden? Ich habe es versucht, {{true}}aber es gibt immer noch den Zeichenfolgenwert zurück true.
Peter Boomsma
4

Dies hat bei mir funktioniert und ich denke, es ist HTML5-kompatibler. Sie sollten Ihr HTML ändern, um das Präfix 'data-' zu verwenden

<div data-example-directive data-number="99"></div>

Und innerhalb der Direktive lesen Sie den Wert der Variablen:

scope: {
        number : "=",
        ....
    },
jmontenegro
quelle
0

Wenn Sie 'exampleDirective' von einer anderen Direktive "benötigen" + befindet sich Ihre Logik im Controller von 'exampleDirective' (sagen wir 'exampleCtrl'):

app.directive('exampleDirective', function () {
    return {
        restrict: 'A',
        scope: false,
        bindToController: {
            myCallback: '&exampleFunction'
        },
        controller: 'exampleCtrl',
        controllerAs: 'vm'
    };
});
app.controller('exampleCtrl', function () {
    var vm = this;
    vm.myCallback();
});
Ilker Cat
quelle