Come ottenere attributi valutati all’interno di una direttiva personalizzata

Sto cercando di ottenere un attributo valutato dalla mia direttiva personalizzata, ma non riesco a trovare il modo giusto di farlo.

Ho creato questo jsFiddle per elaborare.

myApp.directive('myDirective', function () { return function (scope, element, attr) { element.val("value = "+attr.value); } });

Cosa mi manca?

Avviso: aggiorno questa risposta poiché trovo soluzioni migliori. Conservo anche le vecchie risposte per riferimento futuro purché rimangano correlate. La risposta più recente e migliore viene prima.

Risposta migliore:

Le direttive in angularjs sono molto potenti, ma ci vuole tempo per comprendere quali processi si trovano dietro di loro.

Durante la creazione di direttive, angularjs consente di creare un ambito isolato con alcuni collegamenti all’ambito principale. Questi collegamenti sono specificati dall’attributo che si collega l’elemento in DOM e da come si definisce la proprietà dell’ambito nell’object definizione direttiva .

Esistono 3 tipi di opzioni di collegamento che è ansible definire in ambito e che si scrive come attributo relativo ai prefissi.

 angular.module("myApp", []).directive("myDirective", function () { return { restrict: "A", scope: { text: "@myText", twoWayBind: "=myTwoWayBind", oneWayBind: "&myOneWayBind" } }; }).controller("myController", function ($scope) { $scope.foo = {name: "Umur"}; $scope.bar = "qwe"; }); 

HTML

 

In tal caso, nell’ambito di applicazione della direttiva (che si tratti della funzione di collegamento o del controller), possiamo accedere a queste proprietà in questo modo:

 /* Directive scope */ in: $scope.text out: "hello qwe" // this would automatically update the changes of value in digest // this is always string as dom attributes values are always strings in: $scope.twoWayBind out: {name:"Umur"} // this would automatically update the changes of value in digest // changes in this will be reflected in parent scope // in directive's scope in: $scope.twoWayBind.name = "John" //in parent scope in: $scope.foo.name out: "John" in: $scope.oneWayBind() // notice the function call, this binding is read only out: "qwe" // any changes here will not reflect in parent, as this only a getter . 

“Ancora OK” Risposta:

Dal momento che questa risposta è stata accettata, ma presenta alcuni problemi, la aggiornerò con una migliore. Apparentemente, $parse è un servizio che non si trova nelle proprietà dell’ambito corrente, il che significa che prende solo espressioni angolari e non può raggiungere l’ambito. {{ , }} espressioni sono compilate mentre angularjs che inizia che significa quando proviamo ad accedervi nel nostro metodo postlink direttive, sono già compilate. ( {{1+1}} è già 2 in direttiva).

Ecco come vorresti usare:

 var myApp = angular.module('myApp',[]); myApp.directive('myDirective', function ($parse) { return function (scope, element, attr) { element.val("value=" + $parse(attr.myDirective)(scope)); }; }); function MyCtrl($scope) { $scope.aaa = 3432; }​ 

.

 
​​​​​​​​

Una cosa che dovresti notare qui è che, se vuoi impostare la stringa del valore, dovresti racchiuderla tra virgolette. (Vedi terzo input)

Ecco il violino con cui giocare: http://jsfiddle.net/neuTA/6/

Vecchia risposta:

Non lo rimuoverò per le persone che possono essere fuorviati come me, nota che l’uso di $eval è perfettamente corretto nel modo corretto per farlo, ma $parse ha un comportamento diverso, probabilmente non ne avrai bisogno per usarlo nella maggior parte di i casi.

Il modo per farlo è, ancora una volta, usare scope.$eval . Non solo compila l’espressione angular, ma ha anche accesso alle proprietà dell’ambito corrente.

 var myApp = angular.module('myApp',[]); myApp.directive('myDirective', function () { return function (scope, element, attr) { element.val("value = "+ scope.$eval(attr.value)); } }); function MyCtrl($scope) { }​ 

Quello che ti manca è $eval .

http://docs.angularjs.org/api/ng.$rootScope.Scope#$eval

Esegue l’espressione sull’ambito corrente restituendo il risultato. Qualsiasi eccezione nell’espressione viene propagata (non appunto). Questo è utile quando si valutano le espressioni angolari.

Per un valore di attributo che deve essere interpolato in una direttiva che non utilizza un ambito isolato, ad es.

  

usa il metodo degli attributi $observe :

 myApp.directive('myDirective', function () { return function (scope, element, attr) { attr.$observe('value', function(actual_value) { element.val("value = "+ actual_value); }) } }); 

Dalla pagina direttiva ,

osservando gli attributi interpolati: Utilizzare $observe per osservare le variazioni di valore degli attributi che contengono l’interpolazione (ad esempio src="{{bar}}" ). Non solo è molto efficiente, ma è anche l’unico modo per ottenere facilmente il valore reale perché durante la fase di collegamento l’interpolazione non è stata ancora valutata e quindi il valore è in questo momento impostato su undefined .

Se il valore dell’attributo è solo una costante, ad es.

  

puoi usare $ eval se il valore è un numero o booleano e vuoi il tipo corretto:

 return function (scope, element, attr) { var number = scope.$eval(attr.value); console.log(number, number + 1); }); 

Se il valore dell’attributo è una costante di stringa o se si desidera che il valore sia di tipo stringa nella direttiva, è ansible accedervi direttamente:

 return function (scope, element, attr) { var str = attr.value; console.log(str, str + " more"); }); 

Nel tuo caso, tuttavia, dal momento che vuoi supportare valori e costanti interpolati, usa $observe .

Le altre risposte qui sono molto corrette e preziose. Ma a volte basta semplicemente: ottenere un semplice valore parsed alla istanza della direttiva, senza la necessità di aggiornamenti e senza problemi con l’ambito isolato. Ad esempio, può essere utile fornire un carico utile dichiarativo nella propria direttiva come array o object hash nel modulo:

 my-directive-name="['string1', 'string2']" 

In tal caso, puoi tagliare l’inseguimento e usare solo una bella base angular.$eval(attr.attrName) .

 element.val("value = "+angular.$eval(attr.value)); 

Fiddle che lavora.

Per la stessa soluzione Angularjs directive with ng-Model .
Ecco il codice che risolve il problema.

  myApp.directive('zipcodeformatter', function () { return { restrict: 'A', // only activate on element attribute require: '?ngModel', // get a hold of NgModelController link: function (scope, element, attrs, ngModel) { scope.$watch(attrs.ngModel, function (v) { if (v) { console.log('value changed, new value is: ' + v + ' ' + v.length); if (v.length > 5) { var newzip = v.replace("-", ''); var str = newzip.substring(0, 5) + '-' + newzip.substring(5, newzip.length); element.val(str); } else { element.val(v); } } }); } }; }); 

DOM HTML

  

Il mio risultato è:

 92108-2223 
 var myApp = angular.module('myApp',[]); myApp .directive('myDirective', function ($timeout) { return function (scope, element, attr) { $timeout(function(){ element.val("value = "+attr.value); }); } }); function MyCtrl($scope) { } 

Usa $ timeout perché la chiamata direttiva dopo dom carica così le tue modifiche non si applicano

Molte buone risposte qui, ma a volte vuoi solo una soluzione semplice, facile, vecchia, jQuery-ish.

La mia soluzione non gestisce le modifiche al DOM. Se l’attributo potrebbe cambiare, non usare il mio metodo!

Nel mio caso avevo un elemento e avevo bisogno di recuperare il valore di un attributo (rel).

Modello:

 

Nella mia direttiva:

 var buttons = element[0].querySelectorAll('button'); for (var i=0; i