2011-08-21 24 views
36

Tengo 2 modelos y una colección. JobSummary es un modelo, JobSummaryList es una colección de artículos JobSummary, y luego tengo un modelo JobSummarySnapshot que contiene una JobSummaryList:Backbone.js modelo con la colección

JobSummary = Backbone.Model.extend({}); 

JobSummaryList = Backbone.Collection.extend({ 
    model: JobSummary 
}); 

JobSummarySnapshot = Backbone.Model.extend({ 
    url: '/JobSummaryList', 

    defaults: { 
     pageNumber: 1, 
     summaryList: new JobSummaryList() 
    } 
}); 

Cuando llamo fetch en el objeto JobSummarySnapshot, se pone todo ... excepto cuando moverse a través de la colección summaryList todos son de tipo object y no JobSummary.

Supongo que esto tiene sentido ya que, aparte del objeto defaults, no se sabe que el summaryList debe ser del tipo JobSummaryList. Puedo revisar cada elemento y convertirlo en un objeto JobSummary, pero esperaba que hubiera una forma de hacerlo sin tener que hacerlo manualmente.

Aquí está mi código de prueba (de trabajo jsfiddle here):

var returnData = { 
    pageNumber: 3, 
    summaryList: [ 
     { 
     id: 5, 
     name: 'name1'}, 
    { 
     id: 6, 
     name: 'name2'} 
    ] 
}; 

var fakeserver = sinon.fakeServer.create(); 
fakeserver.respondWith('GET', '/JobSummaryList', [200, 
{ 
    'Content-Type': 'application/json'}, 
           JSON.stringify(returnData)]); 

var callback = sinon.spy(); 


var summarySnapshot = new JobSummarySnapshot(); 
summarySnapshot.bind('change', callback); 

summarySnapshot.fetch(); 
fakeserver.respond(); 

var theReturnedList = callback.getCall(0).args[0].attributes.summaryList; 

_.each(theReturnedList, function(item) { 
    console.log('Original Item: '); 
    console.log(item instanceof JobSummary); // IS FALSE 
    var convertedItem = new JobSummary(item); 
    console.log('converted item: '); 
    console.log(convertedItem instanceof JobSummary); // IS TRUE 
}); 

ACTUALIZACIÓN: Se me ocurrió que podría invalidar la función de análisis y establecer de esa manera ... tengo esto ahora:

JobSummarySnapshot = Backbone.Model.extend({ 
    url: '/JobSummaryList', 

    defaults: { 
     pageNumber: 1, 
     summaryList: new JobSummaryList() 
    }, 

    parse: function(response) { 
     this.set({pageNumber: response.pageNumber}); 

     var summaryList = new JobSummaryList(); 
     summaryList.add(response.summaryList); 

     this.set({summaryList: summaryList}); 
    } 
}); 

Esto funciona hasta ahora. Dejando la pregunta abierta en caso de que alguien la haya comentado ...

Respuesta

55

Su función parse() no debería ser , es una práctica mejor simplemente devolver los atributos, Backbone se encargará de configurarla. p.ej.

parse: function(response) { 
    response.summaryList = new JobSummaryList(response.summaryList); 
    return response; 
} 

Lo que regrese de parse() es passed to set().

No devolver nada (que es como volver undefined) es lo mismo que llamar set(undefined), lo que podría hacer que no pasa la validación, o algunos otros resultados inesperados si su aduana validate()/set() métodos de espera para obtener un objeto. Si su validación o el método set() falla debido a eso, no se llamará a la devolución de llamada options.success pasada al Backbone.Model#fetch().

Además, para hacer esto más genérica, de modo que set() ing a un objeto liso de otros lugares (y no sólo de la respuesta del servidor) también afecta a él, es posible que desee anular set() lugar:

set: function(attributes, options) { 
    if (attributes.summaryList !== undefined && !(attributes.summaryList instanceof JobSummaryList)) { 
     attributes.summaryList = new JobSummaryList(attributes.summaryList); 
    } 
    return Backbone.Model.prototype.set.call(this, attributes, options); 
} 

También puede encontrar Backbone-relational interesante - hace que sea mucho más fácil tratar con colecciones/modelos anidados dentro de los modelos.

edición que se olvidó de volver del método set(), el código se ha actualizado

+0

muchas gracias. He sido culpable de leer solo la mitad de las cosas hoy y una vez más, me mordió. Claramente dice en los documentos que, como mencionas arriba, devuelves el obj de la función de análisis ... Pero de alguna manera me perdí eso. Gracias de nuevo. –

+1

¡AMA el ejemplo 'set'! – Bart

Cuestiones relacionadas