2013-04-30 27 views
37

Ho una direttiva di attributo AngularJS e vorrei eseguire un'azione ogni volta che cambia il valore dell'input genitore. In questo momento lo sto facendo con jQuery:AngularJS - Modifica del valore di input della direttiva Attribute

angular.module("myDirective", []) 
.directive("myDirective", function() 
{ 
    return { 
     restrict: "A", 
     scope: 
     { 
      myDirective: "=myDirective" 
     }, 
     link: function(scope, element, attrs) 
     { 
      element.keypress(function() 
      { 
       // do stuff 
      }); 
     } 
    }; 
}); 

C'è un modo per farlo senza jQuery? Sto scoprendo che l'evento keyPress non sta facendo esattamente quello che voglio, e mentre sono sicuro che troverò una soluzione, divento un po 'nervoso quando ricorrerò a jQuery in un progetto Angular.

Quindi qual è il modo angolare per fare questo?

risposta

61

C'è un grande esempio nelle AngularJS documentazione qui:

http://docs.angularjs.org/api/ng.directive:ngModel.NgModelController

E 'molto ben commentato e dovrebbe farti puntato nella giusta direzione.

Un semplice esempio, forse di più quello che stai cercando è qui di seguito:

http://jsfiddle.net/mb98y/

HTML

<div ng-app="myDirective" ng-controller="x"> 
    <input type="text" ng-model="test" my-directive> 
</div> 

JavaScript

angular.module('myDirective', []) 
    .directive('myDirective', function() { 
    return { 
     restrict: 'A', 
     link: function (scope, element, attrs) { 
      scope.$watch(attrs.ngModel, function (v) { 
       console.log('value changed, new value is: ' + v); 
      }); 
     } 
    }; 
}); 

function x($scope) { 
    $scope.test = 'value here'; 
} 

Modifica Stessa cosa , non è richiesto ire ngModel (http://jsfiddle.net/mb98y/1/):

JavaScript:

angular.module('myDirective', []) 
    .directive('myDirective', function() { 
    return { 
     restrict: 'A', 
     scope: { 
      myDirective: '=' 
     }, 
     link: function (scope, element, attrs) { 
      // set the initial value of the textbox 
      element.val(scope.myDirective); 
      element.data('old-value', scope.myDirective); 

      // detect outside changes and update our input 
      scope.$watch('myDirective', function (val) { 
       element.val(scope.myDirective); 
      }); 

      // on blur, update the value in scope 
      element.bind('propertychange keyup paste', function (blurEvent) { 
       if (element.data('old-value') != element.val()) { 
        console.log('value changed, new value is: ' + element.val()); 
        scope.$apply(function() { 
         scope.myDirective = element.val(); 
         element.data('old-value', element.val()); 
        }); 
       } 
      }); 
     } 
    }; 
}); 

function x($scope) { 
    $scope.test = 'value here'; 
} 
+0

Che potrebbe funzionare. Qualche idea su come farlo senza richiedere un modello? Mi piacerebbe solo aggiungere la direttiva. –

+3

Se si desidera che la direttiva funga da 'ngModel', è possibile utilizzare l'ambito isolato con un binding bidirezionale, mostrato qui: http://jsfiddle.net/langdonx/djtQR/ – Langdon

+0

Sto già utilizzando la direttiva, Ho paura, ma grande suggerimento. –

10

Dal momento che questo deve avere un elemento di input come un genitore, si potrebbe utilizzare

<input type="text" ng-model="foo" ng-change="myOnChangeFunction()"> 

In alternativa, è possibile utilizzare la ngModelController e aggiungere una funzione a $formatters, che esegue le funzioni sulla modifica dell'ingresso. Vedi http://docs.angularjs.org/api/ng.directive:ngModel.NgModelController

.directive("myDirective", function() { 
    return { 
    restrict: 'A', 
    require: 'ngModel', 
    link: function(scope, element, attr, ngModel) { 
     ngModel.$formatters.push(function(value) { 
     // Do stuff here, and return the formatted value. 
     }); 
    }; 
}; 
+1

I formattatori $ si attivano solo al caricamento della pagina. $ parser si attiva in caso di cambio di input. – SoEzPz

0

fare attenzione i cambiamenti runtime di valore di una direttiva personalizzato, utilizzare $observe metodo attrs oggetto, invece di mettere $watch all'interno di una direttiva personalizzato. Ecco la documentazione per lo stesso ... $observe docs

Problemi correlati