2013-09-07 9 views
7

Rozważ this Plunkr.AngularJS: Jak powinienem zaktualizować właściwość na rozwiązanej obietnicy w moim detektorze?

Wewnątrz mojego obserwatora zegarka chcę zaktualizować właściwość w ramach rozwiązanej obietnicy.

  • Czy jest prawidłowe modyfikowanie wartości w obiekcie $$v?
  • Jeśli nie, to co powinienem zrobić?

Oto 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> 

Oto 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

innych odpowiedzi zrobić dobrą robotę rozwiązania tego konkretne pytanie; Należy jednak zauważyć, że każda zmienna lub własność w Angular z prefiksem '$$' jest zmienną prywatną i nie powinna być modyfikowana ani zależna od niej. –

+0

@BrandonTilley: Podejrzewałem tyle, ale czuję, że dokumentacja AngularJS powinna gdzieś to powiedzieć i powiedzieć ludziom, co mają robić. –

Odpowiedz

7

nie będę modyfikować $$v bezpośrednio, to szczegółów wdrażania. Zamiast tego użyj then, aby uzyskać wynik obietnicy, a następnie użyj go, jak chcesz. To wymaga minimalnej zmiany w twoim kodzie.

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

Dzięki Buu! To był utwór, którego potrzebowałem, aby uzyskać zegarek na obietnicy, która została zwrócona z funkcji do pracy w moim kodzie ... Awesome! –

+0

@JamesEby nie ma za co, cieszę się, że to pomaga :) –

3

To jest trochę dziwne, aby zmodyfikować obietnicę ponieważ obietnicą reprezentuje wynik akcja wykonywana asynchronicznie. Jest samowystarczalny.

Myślę, że lepiej jest dodać kolejną funkcję usługi, aby zaktualizować dane statusu. Spróbuj tego

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

Interesujące. Wygląda na to, że utrzymujesz stan w serwisie i widziałem, że inni ludzie zalecają to samo. –

+0

@JimG. Technicznie możesz obsługiwać dane w dowolnym miejscu. Należy jednak wykonać tę usługę w sposób samowystarczalny, a ponadto można ją łatwiej kontrolować i łatwiej ją konserwować. I lepiej użyj wywołania funkcji, aby zaktualizować dane, a nie sposobu zademonstrowanego w innej odpowiedzi. – zsong

+0

Jeśli widok zmienia bezpośrednio Ciężar, dlaczego stan aktualizacji kontrolera jest zły? Stworzenie zupełnie nowej metody w usłudze, aby zmodyfikować odsłoniętą właściwość, nie przypomina mi JavaScript (lub AngularJS). –

Powiązane problemy