2012-04-04 9 views
13

Busco una solución mejor para dos cosas:Backbone.js: elegante manera de comprobar si los datos de lista y si el conjunto de datos está vacía

  • ¿Cómo puedo entender si los datos se trae y listo , Uso BasicDealList.on("reset", function(){}) para entender si los datos se obtienen de ajax y se analizan y están listos para ser utilizados, pero se siente sucio.

  • Si un JSON vacío viene de ir a buscar tal como {}, todavía muestra BasicDealList.length como 1, mientras que debería ser 0 así que estaba obligado a comprobar si el primer elemento está vacía a través de collection.length == 1 && jQuery.isEmptyObject(BasicDealList.toJSON()[0] que es muy feo.

Aquí está el código:

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(); 

Respuesta

25

Si no te gusta escuchar reset, puede pasar una devolución de llamada directamente a .fetch():

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

Si, más tarde en su aplicación, desea saber si ya ha obtenido los datos, por lo general solo puede marcar BasicDealList.length. Si desea evitar hacer repetidas solicitudes de colecciones que están realmente vacías en el servidor, es probable que deba encontrar una solución personalizada, p. el establecimiento de una bandera en .fetch():

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

En cuanto a la cuestión de los datos vacía, usted debe devolver [] desde el servidor en lugar de {}. La Colección de Backbone llama al this.add(models, ...) dentro de .reset(), y .add() comprueba si el argumento models es una matriz; si no es así, que lo envuelve en una:

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

Así pasa {} resultará en models conjunto de [{}], que no es lo que desea. Si no puede controlar el servidor, puede hacer la verificación de {} en un método personalizado .parse(), devolviendo [] si se encuentra.

+0

¡Muchas gracias por la explicación detallada! – Hellnar

7

Necesitábamos una forma de saber si la relación de un RelationalModel había sido extraída o no. Esta es nuestra solución (en Coffeescript).

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

Sé que esta pregunta ya ha sido respondida, pero aquí hay una 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. 
}); 

La principal ventaja de esto es que estamos utilizando la función "cuando". La función "cuándo" nos da la posibilidad de verificar múltiples llamadas de búsqueda y tener éxito.

$.when(deferredOne, deferredTwo, deferredThree).then(function() { 
    // do stuff when we have the data. 
}); 

Además, si almacenamos el objeto diferido en una variable, podemos hacer cosas como esta. La variable será una bandera para hacernos saber que ya cargamos los datos.

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

Cuando llamamos a fetch() en una colección, devuelve un objeto jQuery diferido.Un objeto diferido de jQuery puede estar en 3 estados, "pendiente", "rechazado" o "resuelto", y una vez que tengamos los datos, se establecerá el estado del objeto diferido para resolver.

Cuestiones relacionadas