2013-09-07 5 views
7

Betrachten this Plunkr.AngularJS: Wie aktualisiere ich eine Eigenschaft auf einem aufgelösten Versprechen innerhalb meines Watch-Listeners?

Innerhalb meines Watch-Listeners möchte ich eine Eigenschaft auf einem aufgelösten Versprechen aktualisieren.

  • Ist es richtig, Werte auf der $$v Eigenschaft zu ändern?
  • Wenn nicht, was soll ich tun? Hier

ist die HTML:

<!DOCTYPE html> 
<html id="ng-app" ng-app="myAngularApp"> 

    <head> 
    <script data-require="[email protected]*" data-semver="1.2.0-rc2" src="http://code.angularjs.org/1.2.0-rc.2/angular.js"></script> 
    <script src="script.js"></script> 
    </head> 

    <body ng-controller="MyController"> 
    <input ng-model="myDto.Weight" />{{myDto.Status}} 
    </body> 

</html> 

Hier ist die JavaScript:

var myDto = {Weight: 200, Status: 'Acceptable'}; 

var myAngularApp = angular.module('myAngularApp', []); 

myAngularApp.factory('myService', function($q){ 
    return { 
    getMyDto: function(){ 
     var deferred = $q.defer(); 
     deferred.resolve(myDto); 
     return deferred.promise; 
    } 
    }; 
}); 

myAngularApp.controller('MyController', function MyController($scope, myService){ 
    $scope.myDto = myService.getMyDto(); 
    $scope.$watch('myDto.Weight', function(newVal, oldVal){ 
    if (newVal < 150) { 
     $scope.myDto.$$v.Status = 'Too Light!'; // Is this the recommended way of doing it? 
    } 
    else if (500 < newVal) { 
     $scope.myDto.$$v.Status = 'Too Heavy!'; 
    } 
    else if (Number(newVal)) { 
     $scope.myDto.$$v.Status = 'Acceptable'; 
    } 
    else { 
     $scope.myDto.$$v.Status = 'Not a number!'; 
    } 
    }); 
}); 
+0

Die anderen Antworten machen einen guten Job diese spezifische Frage der Adressierung; Es sollte jedoch angemerkt werden, dass jede Variable oder Eigenschaft in Angular mit dem Präfix '$$' eine private Variable ist und nicht modifiziert oder davon abhängig sein sollte. –

+0

@BrandonTilley: Ich vermute so viel, aber ich fühle mich wie die AngularJS-Dokumentation sollte dies irgendwo heraus aufrufen und den Leuten sagen, was zu tun ist. –

Antwort

7

Ich würde $$v direkt nicht ändern, es ist eine Implementierung Detail. Verwenden Sie stattdessen then, um das Ergebnis des Versprechens zu erhalten, und verwenden Sie es dann, wie Sie möchten. Das erfordert minimale Änderungen an Ihrem Code.

Demo link

myAngularApp.controller('MyController', function MyController($scope, myService){ 
    ($scope.myDto = myService.getMyDto()).then(function(myDto) { 
    $scope.$watch('myDto.Weight', function(newVal, oldVal){ 
     if (newVal < 150) { 
     myDto.Status = 'Too Light!'; // Is this the recommended way of doing it? 
     } 
     else if (500 < newVal) { 
     myDto.Status = 'Too Heavy!'; 
     } 
     else if (Number(newVal)) { 
     myDto.Status = 'Acceptable'; 
     } 
     else { 
     myDto.Status = 'Not a number!'; 
     } 
    }); 
    }); 
}); 
+0

Danke Buu! Dies war das Stück, das ich brauchte, um meine versprochene Variable zu sehen, die von einer Funktion zurückgegeben wurde, um in meinem Code zu arbeiten ... Super! –

+0

@JamesEby du bist willkommen, froh, dass es hilft :) –

3

Es ist ein wenig seltsam, das Versprechen, da ein Versprechen zu modifizieren, stellt das Ergebnis eine Aktion, die asynchron ausgeführt wird. Es ist in sich geschlossen.

Ich denke, es ist besser, eine weitere Service-Funktion hinzuzufügen, um Daten den Status zu aktualisieren. Versuchen Sie, diese

myAngularApp.factory('myService', function ($q) { 
    var deferred = $q.defer(); 
    return { 
     getMyDto: function() { 
      deferred.resolve(myDto); 
      return deferred.promise; 
     }, 
     updateStatus: function (status) { 
      myDto.Status = status; 
      deferred.resolve(myDto); 
      return deferred.promise; 
     } 
    }; 
}); 

myAngularApp.controller('MyController', function MyController($scope, myService) { 
    $scope.myDto = myService.getMyDto(); 
    $scope.$watch('myDto.Weight', function (newVal, oldVal) { 
     if (newVal < 150) { 
      myService.updateStatus('Too Light!'); 
     } else if (500 < newVal) { 
      myService.updateStatus('Too Heavy!'); 
     } else if (Number(newVal)) { 
      myService.updateStatus('Acceptable'); 
     } else { 
      myService.updateStatus('Not a number!'); 
     } 
    }); 
}); 

Updated Plunker

+0

Interessant. Es sieht so aus, als ob du den Staat im Dienst hältst, und ich habe andere Leute gesehen, die das gleiche empfehlen. –

+0

@ JimG. Technisch können Sie mit den Daten überall umgehen. Allerdings sollten Sie den Service in sich geschlossen machen, er ist testbarer und leicht zu pflegen. Und Sie sollten einen Funktionsaufruf verwenden, um die Daten zu aktualisieren, nicht wie in der anderen Antwort gezeigt. – zsong

+0

Wenn die Ansicht das Gewicht direkt ändert, warum ist es dann so schlecht, dass der Controller den Status "Update" hat? Erstellen einer ganz neuen Methode im Service, nur um eine exponierte Eigenschaft zu ändern, es fühlt sich nicht wie JavaScript (oder AngularJS) für mich an. –