2014-08-28 14 views
5

Ich versuche, zwischen interner Änderung und einer externen Änderung mit einem bidirektionalen datengebundenen Attribut ('=') zu unterscheiden.

Mit anderen Worten: Ich möchte $watch nicht auf den Wert auslösen, wenn die Änderung intern war (d. H. Die Bereichsvariable wurde in der Steuerung oder in der Link-Funktion geändert).

Hier einige Code, der mein Problem zeigt:

HTML

<div ng-app="myApp">   
    <div ng-controller="MainCtrl"> 
    <input ng-model="value"/> 
    <mydemo value="value"></mydemo> 
    </div> 
</div> 

Javascript

app.directive('mydemo', function() { 
    return { 
    restrict: 'E', 
    scope: { 
     value: "=" 
    }, 
    template: "<div id='mydiv'>Click to change value attribute</div> Value:{{value}}", 

    link: function (scope, elm) 
    {  
     scope.$watch('value', function (newVal) { 
     //Don't listen if the change came from changeValue function 
     //Listen if the change came from input element 
     }); 
     // Otherwise keep any model syncing here. 

     var changeValue = function() 
     { 
     scope.$apply(function() 
     { 
      scope.value = " from changeValue function"; 
     }); 
     } 

     elm.bind('click', changeValue); 
    } 
    } 
}) 

Live-Demo: http://jsfiddle.net/B7hT5/11/

Irgendeine Idee wer kann ich unterscheiden?

Antwort

7

Es gibt keine Möglichkeit, zwischen diesen beiden Ereignissen zu unterscheiden. Sie müssen dieses Verhalten also selbst implementieren.

Ich würde es tun, indem Sie eine Flagge setzen, wenn Sie eine Änderung "intern" machen, dann nach ihr in der Uhr suchen.

Zum Beispiel:

link: function (scope, elm){  

    var internal = false; 

    scope.$watch('value', function (newVal) { 
    if(internal) return internal = false; 
    // Whatever code you want to run on external change goes here. 
    console.log(newVal); 
    }); 

    var changeValue = function(){ 
    scope.$apply(function(){ 
     internal = true; // flag internal changes 
     scope.value = " from changeValue function";        
    }); 
    } 

    elm.bind('click', changeValue); 
} 

Siehe updated fiddle.

Ihr alternativer (komplexerer) Ansatz besteht im Erstellen einer benutzerdefinierten Anweisung, die die API ngModel verwendet. Das unterscheidet zwischen DOM -> Modell (extern) und Modell -> DOM (intern) Änderungen. Ich denke nicht, dass es hier notwendig ist.

+0

Danke ... Ich dachte, es gibt eine einfache und elegante Lösung für dieses Problem ... – cheziHoyzer

Verwandte Themen