2012-04-04 1 views
13

Sto cercando una soluzione migliore per due cose:Backbone.js: modo elegante per controllare se i dati pronti e se il set di dati è vuota

  • Come posso capire se i dati vengono recuperati e pronto , Io uso BasicDealList.on("reset", function(){}) per capire se i dati vengono recuperati da ajax e analizzati e pronti per essere utilizzati, ma si sente sporco.

  • Se un JSON vuoto viene dal recupero come {}, mostra ancora come BasicDealList.length 1 mentre dovrebbe essere 0 quindi sono stato costretto a controllare se il primo elemento è vuoto tramite collection.length == 1 && jQuery.isEmptyObject(BasicDealList.toJSON()[0] che è molto brutto.

Ecco il codice:

BasicDeal = Backbone.Model.extend();  
BasicDealCollection = Backbone.Collection.extend({ 
    model: BasicDeal, 
    url: '/some/ajax/url/', 
}); 
BasicDealList = new BasicDealCollection(); 

BasicDealList.on("reset", function(collection, response){ 
    isEmpty = collection.length == 1 && jQuery.isEmptyObject(BasicDealList.toJSON()[0]); 
    if (isEmpty){ 
    // render no deal found html 
    } 
    else{ 
    // render list of deals 
    } 
} 
BasicDealList.fetch(); 

risposta

25

Se non ti piace ascoltare per reset, è possibile passare un richiamata direttamente a .fetch():

BasicDealList.fetch({ 
    success: function(collection, response){ 
     // ... 
    } 
}); 

Se, più avanti nel app, vuoi sapere se hai già recuperato i dati, di solito puoi semplicemente controllare BasicDealList.length. Se vuoi evitare di fare richieste ripetute per le raccolte che sono effettivamente vuote sul server, probabilmente dovrai elaborare una soluzione personalizzata, ad es. impostazione di un flag su .fetch():

BasicDealList.fetch({ 
    success: function(collection, response){ 
     BasicDealList.fetched = true; 
     // ... 
    } 
}); 

quanto riguarda la questione dei dati vuota, si dovrebbe essere ritornando [] dal server al posto di {}. La collezione Backbone chiama this.add(models, ...) all'interno di .reset() e .add() controlla se l'argomento models è un array; se non lo è, si avvolge in uno:

models = _.isArray(models) ? models.slice() : [models]; 

Quindi passando {} si tradurrà in models insieme a [{}], che non è quello che si desidera. Se non riesci a controllare il server, puoi eseguire il controllo di {} in un metodo personalizzato .parse(), restituendo [] se trovato.

+0

Grazie mille per la spiegazione dettagliata! – Hellnar

7

Avevamo bisogno di un modo per capire se una relazione di RelationalModel era stata recuperata o meno. Questa è la nostra soluzione (in Coffeescript).

initialize: (objects, options) -> 
    @fetched = false 
    @listenTo @, 'sync', -> @fetched = true 
12

So che questa domanda ha già avuto risposta, ma qui è un'alternativa.

BasicDealCollection = Backbone.Collection.extend({ 
    model: BasicDeal, 
    url: '/some/ajax/url/', 
}); 

myCollection = new BasicDealCollection() 
deferred = myCollection.fetch() 

$.when(deferred).then(function() { 
    // do stuff when we have the data. 
}); 

Il vantaggio chiave di questo è che stiamo utilizzando la funzione "quando". La funzione "quando" ci dà la possibilità di controllare più chiamate fetch e fare un successo.

Inoltre, se abbiamo memorizzato l'oggetto posticipato in una variabile, possiamo fare cose come questa. La variabile sarà una bandiera per farci sapere che abbiamo già caricato i dati.

if (deferred.state() === "resolved") { 
    // do stuff when we have the data. 
} 

Quando chiamiamo fetch() su una raccolta restituisce un oggetto differito jQuery.Un oggetto rinviato jQuery può essere in 3 stati, "in sospeso", "rifiutato" o "risolto" e una volta ottenuti i dati, verrà impostato lo stato dell'oggetto posticipato da risolvere.