Come faccio a passare più attributi in una direttiva di attributi Angular.js?


116

Ho una direttiva sugli attributi limitata come segue:

 restrict: "A"

Devo passare due attributi; un numero e una funzione / callback, accedendovi all'interno della direttiva utilizzando l' attrsoggetto.

Se la direttiva fosse una direttiva elemento, limitato con "E"potrei a questo:

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

Tuttavia, per ragioni che non approfondirò, ho bisogno che la direttiva sia una direttiva di attributo.

Come si passano più attributi in una direttiva di attributi?


Dipende dal tipo di ambito creato dalla direttiva (se presente). Le scelte sono: nessun nuovo ambito (predefinito o esplicito con scope: false), nuovo ambito (con normale ereditarietà prototipale, cioè scope: true) e isolare l'ambito (cioè, scope: { ... }). Che tipo di ambito crea la tua direttiva?
Mark Rajcok

1
@MarkRajcok Ha un ambito isolato.
Undistraction

Risposte:


202

La direttiva può accedere a qualsiasi attributo definito sullo stesso elemento, anche se la direttiva stessa non è l'elemento.

Modello:

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

Direttiva:

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

Se il valore dell'attributo example-numbersarà hardcoded, suggerisco di usarlo $evaluna volta e di memorizzare il valore. La variabile numavrà il tipo corretto (un numero).


Ho modificato l'HTML di esempio per utilizzare il caso del serpente. So di non poterlo usare come elemento. Questo è il punto della domanda.
Undistraction

@ Pedr, sì, scusa se ho letto troppo velocemente sull'utilizzo dell'elemento. Ho aggiornato la risposta, notando che è necessario utilizzare anche il caso del serpente per gli attributi.
Mark Rajcok

Nessun problema. Grazie per la tua risposta. Ho modificato i nomi degli attributi per utilizzare il caso del serpente. Stai bene se lo rimuovo dalla tua risposta perché è stato solo uno stupido errore da parte mia e distrae dal punto della domanda e della risposta effettive?
Undistraction

Non capisco: come fa la direttiva a riconoscere la stessa identica cosa specificata nell'utilizzo della direttiva ("exampleCallback ()") nel suo ambito? ("callback: '& exampleCallback') L'ambito non dovrebbe essere" callback: "& exampleFunction"?
blaster

1
@FredrikL, per molteplici direttive sullo stesso elemento, vedere stackoverflow.com/a/28735005/215945
Mark Rajcok

19

Lo fai esattamente nello stesso modo in cui faresti con una direttiva elemento. Li avrai nell'oggetto attrs, il mio esempio li ha vincolati a due vie tramite l'ambito isolato ma non è necessario. Se stai usando un ambito isolato puoi accedere agli attributi con scope.$eval(attrs.sample)o semplicemente scope.sample, ma potrebbero non essere definiti al collegamento a seconda della tua situazione.

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

usato come:

<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>

9

Puoi passare un oggetto come attributo e leggerlo nella direttiva in questo modo:

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

È possibile inviare un valore booleano utilizzando un oggetto? Ho provato {{true}}ma restituisce ancora il valore della stringa true.
Peter Boomsma

4

Questo ha funzionato per me e penso sia più conforme a HTML5. Dovresti cambiare il tuo html per usare il prefisso "data-"

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

E all'interno della direttiva leggi il valore della variabile:

scope: {
        number : "=",
        ....
    },

0

Se "richiedi" 'exampleDirective' da un'altra direttiva + la tua logica è nel controller 'exampleDirective' (diciamo '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();
});
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.