2013-07-23 13 views
59

È possibile impostare uno $watch su una matrice di oggetti all'interno di un servizio (vorrei che la dichiarazione $watch fosse all'interno del servizio)?

risposta

120

È possibile aggiungere qualsiasi espressione all'insieme di orologi iniettando lo $rootScope e utilizzando una funzione un primo argomento per il metodo $watch. Pseudo-codice:

$rootScope.$watch(function() { 
    return //value to be watched; 
}, function watchCallback(newValue, oldValue) { 
    //react on value change here 
}); 

Non dimenticare il terzo, argomento booleano al metodo $watch. È necessario specificare true se si desidera osservare in profondità un intero oggetto per le modifiche.

+0

se non ti dispiace, vorrei che per sho come tu faccia riferimento al valore del servizio di ritorno dalla prima funzione. Ho fatto del mio meglio, ma non sono riuscito a guardare per i cambiamenti.Lo stesso valore veniva costantemente restituito, ancora e ancora. – Birowsky

+0

@Birowsky Hai provato '$ watchCollection'? –

+0

Questo non aiuta mentre sta guardando il rootScope per l'intera applicazione. – btm1

15

i servizi per loro stessa natura sono come classi e metodi di casa. È possibile impostare un metodo che si chiama dal proprio responsabile del trattamento che è argomento è il campo di applicazione e applica un'espressione di controllo:

app.service('myservice',function(){ 
    this.listen = function($scope) { 
     $scope.$watch(function(){return someScopeValue},function(){ 
      //$scope.dosomestuff(); 
     }); 
    } 
}); 

//your controller 

function myCtrl($scope,myservice) { 
    $scope.listen = function() { 
     myservice.listen($scope); 
    } 

    //call your method 
    $scope.listen(); 
} 

aggiornamento: Se si sta tentando di guardare una variabile locale privato all'interno di un servizio, vedere la accettato rispondi usando $ rootScope. Se stai provando a $ guardare una variabile $ scope all'interno di un ambito locale rispetto a quanto sopra è la soluzione migliore. Stanno ottenendo due cose molto diverse.

+0

Potrebbe sembrare una domanda stupida, ma perché stai mettendo 'myservice.listen ($ scope)' all'interno di una funzione? È per riutilizzarlo facilmente attraverso il codice o c'è qualche motivo importante? Inoltre, se metto l'orologio $ in una fabbrica, funzionerà ancora? –

0

Puoi chiarire cosa vuoi ottenere? Come ho capito, stai ricevendo una serie di oggetti dal server come modello. Poi non è chiaro:

  1. Vuoi verificare se alcuni oggetti nella matrice sono stati cambiati (forse dopo l'ultima chiamata al server nel caso in cui si fa ricorrente pooling)?
  2. Si desidera verificare se alcuni oggetti nell'array sono stati modificati dall'utente tramite alcuni elementi di controllo front-end?

Nel caso 1, non si ha realmente bisogno di utilizzare $ guardare (o meglio $ watchCollection), ma si deve scorrere la matrice che hai ricevuto dal server e verificare i cambiamenti (la stessa cosa $ watchColleciton farebbe). Nel caso in cui l'oggetto è diverso da quello attualmente in tuo possesso - si chiama oggetto. $ Save() su questo elemento.

Nel caso 2, utilizzare $ watchCollection() sull' $ scope passato come parametro alla funzione di servizio o utilizzare $ rootScope se si tiene l'array in $ rootScope.

Posso fornire codice reale per chiarire gli scenari.

0

Ehi, ho appena avuto una situazione in cui ho avuto una configurazione dell'orologio piuttosto grande su 2 controller diversi.

Come io non volevo duplicare qualsiasi codice che ho appena definito in modo da funzionare in mio servizio:

angular 
    .module('invoice') 
    .factory('invoiceState', function() { 
     var invoice = { 
      client_info: { 
       lastname: "", 
       firstname: "", 
       email: "", 
       phone: "", 
       id_client: "", 
       ... 
      } 
     } 
     invoice.watchAccommodation = function (newVal, oldVal) { 
      var accommodation = newVal; 
      //Whatever you would normally have in your watch function 
     } 

allora posso solo chiamare questa funzione l'orologio di qualsiasi controller in cui ho iniettato il servizio

function NewInvoiceCtrl(invoiceState) { 
    $scope.$watch('invoice.accommodation',invoiceState.watchAccommodation, true); 
} 

non ho molta esperienza con AngularJS quindi non posso davvero andare negli aspetti delle prestazioni di questo approccio, ma funziona;)