2013-10-27 14 views

risposta

14

Supponendo che si ottiene una risorsa, e poi metterlo sul $ ambito corrente in modo che possa essere modificato da un utente:

$scope.question = Questions.get({id:"19615328"}); 

si può quindi guardare per i cambiamenti come questo:

// some flag, name it anything 
$scope.userChange = false; 
$scope.$watch('question', function(newValue, oldValue) { 
    if(newValue && newValue != oldValue){ 
     $scope.userChange = true; 
     // if you want to you can even do this, this will trigger on every change though 
     $scope.question.$save(); 
    } 
}, true); 

(Praticamente tutto da qui è il risultato delle domande in più dalla chat di sotto)

Poi ogni volta che vuoi per verificare se è stato modificato $scope.userChange puoi dirti se si è verificata una modifica. E quando si salva l'oggetto, ripristinare $scope.userChange.

Si può anche fare questo

$scope.$watch('question', function() { 
    $scope.question.$save(); 
}, true); 

Ovviamente ci si vuole aggiungere una sorta di valvola a farfalla o di un sistema "di rimbalzo" in modo che aspetta un secondo o giù di lì, una volta che hai questo in atto alcuna modifica del oggetto causerà un salvataggio tramite $scope.$watch.

E nel caso in cui si desidera verificare null, per quando non si è ancora ricevuto l'oggetto effettivo.

$scope.$watch('question', function(newValue, oldValue) { 
    // dont save if question was removed, or just loaded 
    if(newValue != null && oldValue != null){ 
     $scope.question.$save(); 
    } 
}, true); 

Si potrebbe anche avvolgere la chiamata Questions.get, vedere this questions for answers on how you can do this on the service & factory level, a fare qualcosa di simile.

Questions.getAndAutosave = function(options){ 
    var instance = Questions.get(options); 
    $scope.$watch(function(){ 
      return instance; 
     }, 
     function(newValue, oldValue){ 
      if (newValue === oldValue) return; 
      if(newValue != null && oldValue != null){ 
       instance.$save(); 
      } 
     }, true); 
    return instance; 
}; 

Poi ogni volta che si chiama Questions.getAndAutosave, qualunque esso ritorna già essere osservato, e sarà automatica $save 'd. Il motivo per cui facciamo if (newValue === oldValue) return; è dovuto al fatto che lo $watch si attiva non appena lo chiami e quindi cerca le modifiche. Non è necessario salvare la prima chiamata.

+0

Purtroppo il $ orologio sarà anche essere attivato quando viene eseguita $ get, perché $ scope.question cambia da null per oggetto ... voglio qualcosa che avrebbe riferito solo le modifiche non salvate quando l'utente apporta le modifiche, non quando i dati vengono estratti dal server. –

+0

L'idea è di guardarlo _dopo_ si riceve la risposta. O; dare $ guardare un secondo callback, (questo riceve il vecchio e il nuovo valore), in modo da poter verificare se il vecchio valore era nullo. (O se il nuovo valore è nullo? :-)) – Philipp

+0

potresti fornire un esempio pronto? –

1

Ho trovato una soluzione che non tratta il download dei dati dal server come modifica dell'utente ed è implementata direttamente nel servizio stesso. Potrebbe non essere possibile la soluzione più efficiente, ma fornisce esattamente la funzionalità che voglio,

app.factory('testService', ['$resource', '$rootScope', function($resource, $rootScope){ 
var test = $resource('/api/words/:id', {id: '@id'}); 

test.orig_get = test.get; 

test.get = function(options){ 
    var instance = test.orig_get(options, function(){ 
     instance.unsaved = false; 
     $rootScope.$watch(function(){ 
      return instance; 
     }, function(newValue, oldValue) { 
      if(angular.equals(newValue, oldValue)){ 
       return; 
      } 
      var changed_indexes = []; 
      for(var i in newValue){ 
       if(!angular.equals(newValue[i], oldValue[i])){ 
        changed_indexes.push(i); 
       } 
      } 
      if(newValue != null && oldValue != null && !(changed_indexes.length==1 && changed_indexes[0]=='unsaved')){ 
       console.log('detected change. setting unsaved to true'); 
       instance.unsaved = true; 
      } 

     }, true); 
    }); 
    return instance; 
} 

test.prototype.orig_save = test.prototype.$save; 

test.prototype.$save = function(options){ 
    return this.orig_save(options, function(){ 
     this.unsaved = false;   
    }) 
} 

return test; 
}]); 
0

è possibile clonare l'oggetto iniziale, quindi confrontare quando è necessario controllare.

master = null 
resource = Resource.get({id:1}, function() { 
    master = angular.copy(resource) 
}) 
function isModified() { 
    return !angular.equals(resource, master) 
} 
+0

Anche se questo risolve il problema, è molto costoso un confronto tra oggetti. Se usi una funzione come questa nella vista, questo costoso algoritmo di confronto verrà eseguito su ogni ciclo di digestione, rendendo l'app rallentata. –

Problemi correlati