2014-10-03 9 views
7

Sagen, ich habe die folgende Direktive aktualisieren:

myApp.directive('myDirective', function() { 
    return { 
     restrict: 'A', 
     require: 'ngModel', 
     scope: { 
      ngModel: '=' 
     }, 
     link: function(scope, elem, attrs, ngModelCtrl) { 
      scope.$watch('ngModel', function() { 
       ngModelCtrl.$modelValue = 'foo'; 
      }); 
     } 
    } 
}); 

Und die folgende html:

<input ng-model="name" my-directive></input> 

Grundsätzlich, wenn der Benutzer Änderungen Die Eingabe my-directive würde idealerweise den internen Modellwert in "foo" ändern, während der Ansichtswert unverändert bleibt.

Aber wenn ich $scope.name im entsprechenden Controller auszudrucken, ist es nicht log „foo“, meldet er unabhängig vom Benutzer eingegebene in

Es scheint, dass ngModelCtrl.$modelValue ist nicht das, was die Steuerung zugreift. - gehe ich dieses Problem falsch an?

(Auch die ngModel im Rahmen beobachtet wirklich falsch anfühlt, aber ich bin nicht sicher, ob irgendeine andere Art und Weise. Irgendwelche Vorschläge wären sehr willkommen!)

+1

Anstatt ngModel anzusehen, können Sie '$ viewChangeListeners' verwenden, das speziell für diesen Zweck entwickelt wurde. Aber warum willst du '$ modelValue' anders als den viewValue setzen? – PSL

+1

Ich möchte, dass Benutzer in kommagetrennte Daten eingeben können, aber das zugrunde liegende Modell die Informationen als Array speichern. – Cody

+3

Gefällt Ihnen? http://plnkr.co/edit/pWpnup?p=preview – PSL

Antwort

9

Wenn Sie Ansicht ändern suchen, sollen Sie nie Registriere eine Uhr. ngModelControllers $viewChangeListeners wurden speziell für diesen Zweck entwickelt und um zu vermeiden, dass zusätzliche Watch auf dem ngModel erstellt werden. Sie können auch die 2-Wege-Bindung für das ngModel entfernen.

Ich kann auf diese Weise denken.

.directive('myDirective', function($parse) { 
    return { 
     restrict: 'A', 
     require: 'ngModel', 
     link: function(scope, elem, attrs, ngModelCtrl) { 
      /*Register a viewchange listener*/ 
      ngModelCtrl.$viewChangeListeners.push(function(){ 
       /*Set model value differently based on the viewvalue entered*/ 
       $parse(attrs.ngModel).assign(scope, ngModelCtrl.$viewValue.split(',')); 
      }); 
     } 
    } 
}); 

Demo

Während darüber die andere Art und Weise zu denken um (Credits @Cody) es wird knapper und angemessen, während ein $parser verwenden.

ngModelCtrl.$parsers.push(function(val) { return val.split(',') }); 
+3

Zukünftig habe ich '$ parsers' ausgecheckt, und ich denke, ich fand eine etwas prägnantere Lösung: 'ngModelCtrl. $ Parsers.push (function (val) {return val.split (',')})'. – Cody

+0

Nein, du hast Recht .. Ich weiß nicht, warum ich nicht umgekehrt darüber nachgedacht habe, wahrscheinlich wirklich spät zu schlafen, denke ich. :) Hier wird jedes Mal, wenn der Wert geändert wird, auch ein Array dem angModel viewvalue zugewiesen, aber es wird stringifiziert ... – PSL