2013-08-04 5 views
8

J'ai une relation de plusieurs à un que j'essaie de modéliser avec Backbone-Forms que je ne peux pas obtenir de travailler.Liste des modèles imbriqués dans Backbone-Forms

L'idée est qu'il existe de nombreux foos qui sont attachés à une seule barre. La prise est que chaque barre doit avoir au moins un foo. Je veux être en mesure d'avoir un seul formulaire où vous pouvez créer une barre, et autant de foos que vous voulez qui sont attachés à cette barre. La liste Backbone-Forms serait parfaite, malheureusement je ne sais pas comment l'implémenter avec un modèle imbriqué.

Merci.

Répondre

9

Je n'ai jamais utilisé Backbone-Forms auparavant. Mais si je voulais implémenter ceci sans utiliser ce plugin, j'irais comme ça.

J'aurais 2 modèles et 2 collections.

modèles

  • Bar
  • Foo

Collections

  • Bars
  • Foos

j'aurais une méthode d'analyse syntaxique dans Bar modèle qui crée une collection Foo pour chaque modèle.

Vues

  • MainView (Passé dans une collection Bars) et Rendue
  • BarsListView (Créé à partir MainView passé dans la collection Bar)
  • Barview (Passed Bar Model)
  • FooListView (Passé dans la collection de Foo)
  • FooView (passé dans le modèle de Foo)

Quelque chose dans ce sens .. Ceci est juste un exemple grossier

// Models 
var Foo = Backbone.Model.extend({}); 
var Foos = Backbone.Collection.extend({ 
    model : Foo 
}); 
// Collections 
var Bar = Backbone.Model.extend({ 
    initialize: function() { 
     if(typeof this.foos === 'undefined') { 
      this.foos = new Foos(); 
     } 
    }, 
    // Parse method that will attach the 
    // foo list if available to the Bar Model 
    parse: function(resp) { 
     // Storing the collecting direcly on the Model 
     this.foos = new Foos(resp.hobbies || null); 
     delete resp.hobbies; 
     return resp; 
    } 
}); 

var Bars = Backbone.Collection.extend({ 
    model : Bar 
}); 

//Views 
var FooView = Backbone.View.extend({ 
    tagName: 'li', 
    className : 'foo', 
    template: _.template($('#foo-template').html()), 
    render: function() { 
     this.$el.append(this.template(this.model.toJSON())); 
     return this; 
    } 
}); 

var FooListView = Backbone.View.extend({ 
    template: _.template($('#foo-list-template').html()), 
    initialize: function() { 
     this.listenTo(this.collection, 'add', this.renderFooView); 
     this.listenTo(this.collection, 'reset', this.render); 
    }, 
    events:{ 
     'click .add-foo' : 'addFoo' 
    }, 
    addFoo: function() { 
     var newFoo = new Foo({ 
      hobby : $('.foo-name', this.$el).val() 
     }); 
     this.collection.add(newFoo); 
    }, 
    renderFooView: function(foo) { 
     var fooView = new FooView({ 
      model : foo 
     }); 
     $('.foo-list', this.$el).append(fooView.el); 
     fooView.render(); 
    }, 
    render: function() { 
     var thisView = this; 
     this.$el.empty(); 
     this.$el.append(this.template); 
     _.each(this.collection.models, function(foo) { 
      thisView.renderFooView(foo); 
     }); 
     return this; 
    } 
}); 

// Bar View 
var BarView = Backbone.View.extend({ 
    className: 'bar', 
    template: _.template($('#bar-template').html()), 
    renderFooListView: function() { 
     var fooListView = new FooListView({ 
      el: $('.foo-container', this.$el), 
      collection : this.model.foos 
     }); 
     fooListView.render(); 
    }, 
    render: function() { 
     this.$el.append(this.template(this.model.toJSON())); 
     this.renderFooListView(); 
     return this; 
    } 
}); 
// Bar List View 
var BarListView = Backbone.View.extend({ 
    template: _.template($('#bar-list-template').html()), 
    initialize: function() { 
     // Events on collection which will trigger the methods 
     this.listenTo(this.collection, 'add', this.renderBarView); 
     this.listenTo(this.collection, 'reset', this.render); 
    }, 
    events: { 
     'click .add-bar' : 'addBar' 
    }, 
    // Add a new Bar 
    addBar: function() { 
     var newBar = new Bar({ 
      name : $('.bar-name', this.$el).val(), 
      age : $('.bar-age', this.$el).val() 
     }); 
     this.collection.add(newBar); 
    }, 
    // Render BarView for each Model in Bars Collection 
    renderBarView: function(bar) { 
     var barView = new BarView({ 
      model : bar 
     }); 
     $('.bar-container').append(barView.el); 
     barView.render(); 
    }, 
    render: function() { 
     var thisView = this; 
     this.$el.empty(); 
     this.$el.append(this.template); 
     _.each(this.collection.models, function(bar) { 
      thisView.renderBarView(bar); 
     }); 
     return this; 
    } 
}); 
// Main View 
// Renders the BarListView 
var MainView = Backbone.View.extend({ 
    el : $('.main'), 
    renderBarListView: function() { 
     var barListView = new BarListView({ 
      collection : this.collection 
     }); 
     this.$el.append(barListView.el); 
     barListView.render(); 
    }, 
    render: function() { 
     this.$el.empty(); 
     this.renderBarListView(); 
     return this; 
    } 
}); 

// Initial obj 
var obj = [{ 
    "name" : "Brad", 
    "age": 15, 
    "hobbies" : [{"hobby":"play"}, {"hobby": "eat"}] 
},{ 
    "name" : "Micheal", 
    "age": 22, 
    "hobbies" : [{"hobby":"sit"}, {"hobby": "walk"}] 
}]; 

// Bars collection and rendering of Main view 
var bars = new Bars(obj, {parse : true}); 
var mainView = new MainView({ 
    collection : bars 
}); 
mainView.render(); 

Check Fiddle

+0

Ceci est une très belle réponse Sushanth, j'ai commencé une prime pour récompenser votre travail. – Xeoncross

+0

On dirait bien, devrait être d'accord avec Xeon. – thepk

+0

On dirait que je vous ai eu un tas de upvotes aussi. Merci encore! – Xeoncross