2013-03-13 13 views
11

Ecco il mio problema. Per esempio, abbiamo la seguente direttiva, che utilizza alcuni widget di jQuery dietro le quinte:Direttive AngularJS - best practice quando si utilizza ngModel con widget jQuery

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

Quindi, se poi verranno eseguiti il ​​gestore che è registrato utilizzando $ orologio per ascoltare i cambiamenti nel modello cambia il valore del modello, e, di conseguenza, verrà eseguito anche il metodo 'set_value' del widget. Ciò significa che verrà attivato l'evento 'value_updated'.

La mia domanda è: qual è la prassi migliore per implementare comportamenti simili nelle direttive per evitare chiamate extra di gestori di eventi DOM e osservatori?

risposta

4

Invece di scope.$watch(), suggerisco di implementare ctrl.$render(). $ render dovrebbe essere chiamato solo se qualcosa all'interno di Angular cambia il modello. Fiddle example.

Questo risolve un problema che non hai menzionato. Sfortunatamente, non risolve il problema che hai menzionato. Nel violino viene associato un evento blur anziché un evento widget.on(). Forse funzionerebbe per te –, ad esempio, aggiorna il modello solo su sfocatura, anziché su ogni sequenza di tasti (questo presuppone che il tuo widget accetti le sequenze di tasti, comunque).

Forse potresti anche chiedere all'autore del widget di fornire un metodo "set" che non attivi un evento. Quindi potrebbe essere usato nel metodo $ render().

+0

Grazie Mark, la tua soluzione risolve perfettamente il mio problema. Ma potresti dirlo, quando è appropriato usare osservatori e quando l'implementazione di render $? – oaleynik

+2

@oaleynik, $ render() dovrebbe essere implementato ogni volta che si vuole fare qualcosa perché un valore di modello ng è stato modificato all'interno di Angular. ng-model imposta automaticamente l'orologio per noi, e $ render() viene chiamato se nota una modifica. Quindi normalmente, con ng-model, vuoi implementare $ render invece di usare il tuo $ watch. –