2013-09-07 11 views
7

Considerare this Plunkr.AngularJS: come devo aggiornare una proprietà su una promessa risolta all'interno del mio listener di controllo?

All'interno del mio ascoltatore di controllo, vorrei aggiornare una proprietà su una promessa risolta.

  • E 'corretto modificare i valori sulla proprietà $$v?
  • Se no, allora cosa dovrei fare?

Ecco il codice 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> 

Ecco il 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

Le altre risposte fare un buon lavoro di affrontare questo problema specifico; tuttavia, si dovrebbe notare che qualsiasi variabile o proprietà in Angolare con prefisso '$$' è una variabile privata e non deve essere modificata o dipende da. –

+0

@BrandonTilley: Lo sospettavo, ma mi sento come se la documentazione di AngularJS la chiamasse specificatamente da qualche parte e dicessi alla gente cosa invece fare. –

risposta

7

non modificherebbe $$v direttamente, è un dettaglio di implementazione. Invece, usa then per ottenere il risultato della promessa, quindi usalo come preferisci. Ciò richiede modifiche minime al codice.

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

Grazie Bu! Questo era il pezzo di cui avevo bisogno per ottenere il mio orologio su una variabile promessa restituita da una funzione per funzionare nel mio codice ... Fantastico! –

+0

@JamesEby sei il benvenuto, felice che aiuti :) –

3

E 'un po' strano per modificare la promessa dal momento che una promessa rappresenta il risultato di un'azione eseguita in modo asincrono. È autonomo.

Penso che sia meglio aggiungere un'altra funzione di servizio per aggiornare i dati dello stato. Prova questo

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

Interessante. Sembra che tu stia mantenendo lo stato nel servizio, e ho visto altre persone consigliare di fare lo stesso. –

+0

@JimG. Tecnicamente puoi gestire i dati ovunque. Tuttavia, è necessario rendere il servizio autonomo ed è più verificabile e di facile manutenzione. E faresti meglio ad usare una chiamata di funzione per aggiornare i dati, non il modo dimostrato nell'altra risposta. – zsong

+0

Se la vista sta cambiando direttamente Peso, perché è male avere lo stato di aggiornamento del controller? Creando un metodo completamente nuovo nel servizio solo per modificare una proprietà esposta, non mi sembra JavaScript (o AngularJS) per me. –

Problemi correlati