2013-03-13 4 views
11

Hier ist mein Problem. Zum Beispiel haben wir die folgende Anweisung, die einige jQuery Widget hinter den Kulissen verwendet:AngularJS-Direktiven - Best Practices bei Verwendung von ngModel mit jQuery-Widget

module.directive('myWidget', [function() { 
    return { 
     require: "ngModel", 
     restrict: "A", 
     replace: true, 
     templateUrl: "templates/myWidget.html", 
     link: function(scope, element, attrs, ctrl) { 
      element.widget_name().on('value_updated', function(event) { 
       scope.$apply(function() { 
        var newModelValue = event.some_value; 
        ctrl.$setViewValue(newModelValue); 
       }); 
      }); 

      scope.$watch(attrs["ngModel"], function(value){ 
       element.widget_name('set_value', value); 
      }); 
     } 
    }; 
}]); 

Also, wenn Modell der Wert ändert, dann wird der Handler, der $ Uhr registriert verwendet für Änderungen in Modell zu hören ausgeführt werden und folglich wird die Methode 'set_value' des Widgets ebenfalls ausgeführt. Dies bedeutet, dass das 'value_updated'-Ereignis ausgelöst wird.

Meine Frage ist: Was ist die beste Vorgehensweise, um ein ähnliches Verhalten in Direktiven zu implementieren, um zusätzliche Aufrufe von DOM Event Handlern und Watchers zu vermeiden?

Antwort

4

Anstelle von scope.$watch() empfehle ich die Implementierung ctrl.$render(). $ render sollte nur aufgerufen werden, wenn etwas in Angular das Modell ändert. Fiddle example.

Dies löst ein Problem, das Sie nicht erwähnt haben. Leider löst es das von Ihnen erwähnte Problem nicht. In der Fiddle ist ein blur Ereignis gebunden, anstatt irgendein widget.on() Ereignis. Vielleicht würde das für Sie funktionieren –, d. H., Aktualisieren Sie das Modell nur bei Unschärfe und nicht bei jedem Tastendruck (dies setzt jedoch voraus, dass Ihr Widget Tastenanschläge akzeptiert).

Vielleicht könnten Sie auch den Widget-Autor bitten, eine "set" -Methode bereitzustellen, die kein Ereignis auslöst. Dann könnte das in der $ render() Methode verwendet werden.

+0

Dank Mark, Ihre Lösung ist perfekt löst mein Problem. Könntest du mir bitte sagen - wann ist es angemessen, Beobachter zu benutzen und wann die Implementierung von $ render? – oaleynik

+2

@oaleynik, $ render() sollte immer dann implementiert werden, wenn Sie etwas tun möchten, weil ein ng-Modellwert innerhalb von Angular geändert wurde. ng-model richtet automatisch die Uhr für uns ein und $ render() wird aufgerufen, wenn es eine Änderung bemerkt. Normalerweise möchten Sie mit ng-model $ render implementieren, anstatt Ihre eigene $ watch zu verwenden. –