2011-05-19 3 views
6

J'ai une collection BackboneJS appelée History qui peut contenir l'un des plusieurs modèles JS Backbone (qui s'étendent de HistoryItem qui s'étend de Backbone.Model), j'essaie de trouver un moyen de recréer cette chargement, malheureusement, il semble que la collection BackboneJS ne peut spécifier à un modèle particulier par exempleBackbone.Js Collection avec des types spécifiques

HistoryCollection = Backbone.Model.extend({ 
    model: app.models.HistoryItem 
}) 

Ce que je vraiment besoin de faire est de déterminer ce par type, voici ce que je voudrais faire

HistoryCollection = Backbone.Model.extend({ 
    model: function(item) { 
     return app.models[item.type]; } }) 

Toutes les idées avant de la fourche Backbone pour mettre en œuvre ce? (Par exemple, un attribut de modèle de collection pouvant prendre une fonction)

Répondre

7

Jouer autour de firebug .. a proposé une approche où vous pouvez remplacer la méthode d'analyse de collection au lieu de spécifier le modèle. Votre mise en œuvre d'analyse syntaxique devient essentiellement une usine simple pour remplir la collection avec des modèles que vous voulez:

var BaseModel = Backbone.Model.extend({ 
    meth: function(){ return 'Base method'; }, 
}); 

var SubModel = BaseModel.extend({ 
    meth: function(){ return 'Sub1 method'; } 
}); 

var SubModel2 = BaseModel.extend({ 
    meth: function(){ return 'Sub2 method'; } 
}); 

var ModelCollection = Backbone.Collection.extend({ 
    parse: function(data){ 
     var self = this; 
     data.forEach(function(item){ 
      switch(item.type){ 
      case 1: 
       self.add(new SubModel(data)); 
       break; 
      case 2: 
       self.add(new SubModel2(data)); 
       break; 
      default: 
       self.add(new BaseModel(data)) 
     } 
}); 
    } 
}); 

//Example Use 
x = new ModelCollection; 
x.parse([{type: 1},{type: 2}, {type: 99}]); 
x.map(function(e){ return e.meth();}); 
+0

Merci pour cela. Cela m'a aidé à résoudre un problème que j'avais dans une autre question (http://stackoverflow.com/questions/7140741/backbone-js-model-with-collection). Je n'ai jamais pensé à utiliser la fonction d'analyse ... –

0

Je viens mis en œuvre cette fonction et a commencé avec le conseil de Jake Dempsey, mais vous avez réellement besoin de passer outre une méthode différente la collection. Voici le code je:

var MyCollection = Backbone.Collection.extend({ 

    _prepareModel: function(model, options) { 
     if (!(model instanceof Backbone.Model)) { 
      var attrs = model; 

      switch (attrs.type) { 
       case 1 : 
        model = new ModelType1(attrs, { collection: this }); 
        break; 

       case 2 : 
        model = new ModelType2(attrs, { collection: this }); 
        break; 

       default : 
        model = new BaseModel(attrs, { collection: this }); 
        break; 
      } 

      if (model.validate && !model._performValidation(attrs, options)) model = false; 
     } else if (!model.collection) { 
      model.collection = this; 
     } 

     return model; 
    } 

}); 

Notez qu'il est une méthode privée (ish) donc quelque chose à garder à l'esprit lors de la mise à niveau Backbone.

4

à mon humble avis, je préfère jouer avec la méthode de modèle dans la collection:

var MyCollection = Backbone.Collection.extend({ 
    model : function(attrs, options){ 
    switch (attrs.type) { 
      case 1 : 
       model = new ModelType1(attrs, options); 
       break; 

      case 2 : 
       model = new ModelType2(attrs, options); 
       break; 

      default : 
       model = new BaseModel(attrs, options); 
       break; 
    } 
    } 
}); 

ou en utilisant un modèle proxy:

ProxyModel = Backbone.Model.extend({ 
initialize: function() { 
    switch (this.get('type')) { 
    case 1 : 
     model = new ModelType1(attrs, options); 
     break; 

    case 2 : 
     model = new ModelType2(attrs, options); 
     break; 

    default : 
     model = new BaseModel(attrs, options); 
     break; 
    } 
    return new model; 
} 
}) 


var MyCollection = Backbone.Collection.extend({ 
    model : ProxyModel, 
}); 
Questions connexes