2011-08-03 9 views
9

Tengo una colección de Backbone.js y tengo una serie de ID de modelos que deseo rellenar. Sé que podría buscar estos objetos uno por uno, crear una matriz de objetos y pasarlos al constructor de la Colección como una matriz.¿Es posible inicializar una Colección de red troncal con Id. De objeto en lugar de objetos?

Lo que me gustaría hacer es pasar la matriz de identificadores de objeto en el constructor como datos iniciales, y obtener la colección para buscarlos, posiblemente como lote, como por this.

Doable?

Respuesta

10

Cuando llamas a 'buscar' en una Backbone.Collection, a su vez llama a Backbone.sync, que por defecto solo le pide a la colección que use la url.

Así que si su servidor responde a:

/models/batch/?ids=1,2,3,4 

Se podría hacer algo como:

var MyCollection = Backbone.Collection.extend({ 

    model: Model, 

    url: '/models', 

    initialize: function(models, options) { 
     ids = options.ids || []; 
     if (ids.length > 0) { 
      this.fetchByIds(ids); 
     } 
    }, 

    fetchByIds: function(ids) { 
     // Save a reference to the existing url 
     var baseUrl = this.url; 

     // Assign our batch url to the 'url' property and call the server 
     this.url += '/?ids=' + ids.join(','); 
     this.fetch(); 

     // Restore the 'url' property 
     this.url = baseUrl; 
    } 
}); 

y usarlo de esta manera:

var coll = new MyCollection({}, {ids: [1, 2, 3, 4]}); 

que tendría que pasar los ids en el parámetro de opciones, porque la función del constructor Backbone.Collection establece los modelos pasados ​​en el primer parámetro antes llama a la función 'inicializar'.

En teoría, esto debería funcionar (léase: completamente sin probar).

+0

Muchas gracias, lo intentaré – Joe

3

También puede configurar la url para una función. Simplemente anularía fetch en lugar de fetchByIds: Además, creo que baseUrl es solo para el Modelo, no para la Colección. Creo rulfzid tiene la idea correcta, pero creo que lo haría así:

var MyCollection = Backbone.Collection.extend({ 
    model: Model, 

    initialize: function(models, opts) { 
    if (options.ids) { 
     this.fetch(options.ids); 
    } 
    }, 

    url: function() { 
    var url = ''; 
    if (this.fetch_ids) { 
     // pass ids as you would a multi-select so the server will parse them into 
     // a list for you. if it's rails you'd do: id[]= 
     url = '/models?id=' + ids.join('&id='); 
     // clear out send_ids 
     this.fetch_ids = undefined; 
    } else { 
     url = '/models'; 
    } 
    return url; 
    }, 

    fetch: function(args) { 
    if (args.ids) { 
     this.fetch_ids = args.ids; 
    } 
    return Backbone.Model.prototype.fetch.call(this, args); 
    } 
}); 

creo que mantiene la funcionalidad en el 'lugar' adecuado, y que permite una mayor capacidad de reutilización (es decir, se puede recuperar (list_of_ids) en cualquier momento ... no necesita un objeto nuevo)

7

En la carga de la página inicial, no debe usar la función de búsqueda, se debe iniciar como se usa reset que se describe aquí: http://documentcloud.github.com/backbone/#FAQ-bootstrap.

Desde el enlace:

Cargando Bootstrapped Modelos

Cuando la aplicación carga por primera vez, es común tener un conjunto de modelos iniciales que usted sabe que va a necesitar, a fin de hacer la página. En lugar de disparar una solicitud AJAX adicional para recuperarlos, un patrón más agradable es tener sus datos ya iniciados en la página. A continuación, puede usar restablecer para completar sus colecciones con los datos iniciales. En DocumentCloud, en la plantilla de ERB para el espacio de trabajo, hacemos algo en este sentido:

<script> 
    Accounts.reset(<%= @accounts.to_json %>); 
    Projects.reset(<%= @projects.to_json(:collaborators => true) %>); 
</script> 
Cuestiones relacionadas