2013-04-30 9 views
37

Mam dyrektywę atrybutu AngularJS i chciałbym wykonać akcję za każdym razem, gdy zmieni się jej wartość nadrzędna. Teraz robię to z jQuery:AngularJS - zmiana wartości wejściowej dyrektywy atrybutu

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

Czy można to zrobić bez jQuery? Uważam, że zdarzenie keyPress nie działa dokładnie tak, jak chcę, i chociaż jestem pewien, że wymyślę jakieś rozwiązanie, trochę się denerwuję, gdy uciekam się do używania jQuery w projekcie Angular.

Więc jaki jest ten sposób Angular?

Odpowiedz

61

Jest świetnym przykładem w angularjs docs tutaj:

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

To bardzo dobrze skomentowany i powinno Ci wskazał w dobrym kierunku.

Prosty przykład, może więcej, więc co szukasz jest poniżej:

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

Edit samo , nie wymaga 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

To może zadziałać. Każdy pomysł, jak to zrobić, nie wymagając modelu? Chciałbym tylko dodać dyrektywę. –

+3

Jeśli chcesz, aby dyrektywa służyła jako 'ngModel', możesz użyć zakresu izolowania w/dwukierunkowego powiązania, pokazanego tutaj: http://jsfiddle.net/langdonx/djtQR/ – Langdon

+0

Już używam dyrektywy, Obawiam się, ale wspaniała sugestia. –

10

Ponieważ to musi mieć element wejściowy jako rodzic, można po prostu użyć

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

Alternatywnie, można użyć ngModelController i dodać funkcja do $formatters, która wykonuje funkcje przy zmianie wejścia. Zobacz 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

$ formatters strzela tylko przy ładowaniu strony. $ parsers uruchamia się przy zmianie wejścia. – SoEzPz

0

uważać na zmiany wartości w czasie wykonywania dyrektywy niestandardowego, użyj $observe metoda attrs obiektu, zamiast umieszczać $watch wewnątrz dyrektywy niestandardowej. Oto dokumentacja tego samego ... $observe docs

Powiązane problemy