2011-06-09 21 views
10

Tengo el siguiente modelo con la colección anidadapueblan colecciones anidadas con el modelo de los padres traen

var Mdl = Backbone.Model.extend({ 
    initialize: function() { 

    // collection 
    this.col1 = new NestedCollection(); 

    }, 
    ... 
}); 

quisiera enviar los datos para el modelo y los modelos de la colección en una solicitud que buscan algo parecido :

{ 
    att1: val, 
    col1: [{obj1: val}, {...}] 
} 

estoy seguro sobre la mejor manera de entregar los datos de la solicitud a la colección anidada (col1). No puedo hacer ...

var Mdl = Backbone.Model.extend({ 
    initialize: function() { 
    // collection 
    this.col1 = new NestedCollection(this.get('col1'); 
    }, 
    ... 
}); 

... porque en el momento de la inicialización se llama la función de análisis del modelo no se ha llamado lo que significa que el atributo está vacío col1, otra solución pensé fue escuchar por el cambio en el modelo de los padres como ...

model.bind("change:tags", function() { 
    model.col1.refresh(model.get('col1')); 
}); 

Sin embargo esta solución se siente un poco de mano dura y potencialmente podría romper cualquier

this.col1.bind("add", function() {}) 

y

this.col1.bind("remove", function() {}) 

configuración de la función en la colección.

¿Alguien tiene alguna idea de la forma "oficial" de hacer esto?

Gracias.

Respuesta

33

La forma "oficial" es reemplazar el método de análisis:

http://documentcloud.github.com/backbone/#Model-parse

En su caso específico, lo que probablemente no es, en el método de análisis, construir la colección anidada de los datos col1 , elimínelo de los resultados, luego entregue los resultados. Backbone convertirá el resto de los datos en propiedades.

No he probado esto, así que no estoy 100% seguro de que funciona:

parse: function(response) { 
    this.col1 = new NestedCollection(response.col1); 
    delete response.col1 
    return response 
} 

Editar: Nov 28vo 2012

Daño señala que esto podría no ser la mejor manera para hacerlo más. La respuesta original fue escrita hace bastante tiempo, y la pregunta original indicaba que el usuario quería que la colección fuera una propiedad del modelo (no un atributo), pero Harm tiene razón al afirmar que tener la colección como atributo es más aceptado. forma de hacerlo en estos días.

Hoy en día, usted podría utilizar algo como Backbone-Relational para manejar un montón de estas cosas para usted, o, si desea hacerlo usted mismo, y tener la colección como un atributo de modelo, se podría hacer algo como:

Building = Backbone.Model.extend({ 
    parse: function(response) { 
     console.log("Parse Called"); 
     response.rooms = new Rooms(response.rooms); 
     return response; 
    } 
}); 
Room = Backbone.Model.extend({}); 
Rooms = Backbone.Collection.extend({ 
    model: Room 
}); 

science_building = new Building(); 

science_building.fetch(
    {success: function(model,resp) {console.log(resp);}} 
); 

Con un modelo de ir a buscar la respuesta como:

{ id: 1, 
    name: "Einstein Hall", 
    rooms: [ 
    {id:101, name:'Chem Lab'}, 
    {id:201, name:'Physics Lab'}, 
    {id:205, name:'Bio Lab'} 
    ] 
} 

Resultando en un modelo de construcción que permite:

science_building.get('rooms').get(101).get('name') // ==> "Chem Lab" 

Un ejemplo de trabajo jsFiddle: http://jsfiddle.net/edwardmsmith/9bksp/

+0

Perfecto, muchas gracias !! – luxerama

+1

No estoy totalmente de acuerdo con esta solución. 'parse()' debería devolver un montón de atributos. Ahora tiene un efecto secundario extraño de establecer algo directamente en el modelo. Tal vez sea mejor reemplazar el contenido de la clave de recopilación con una colección adecuada de columna vertebral. – harm

+0

+1 para el regreso –

Cuestiones relacionadas