2013-08-04 66 views
8

我有一個多對一的關係,我試圖用Backbone-Forms進行建模,但我無法工作。Backbone-Forms中的嵌套模型列表

這個想法是有很多foos連接到一個酒吧。抓住每個酒吧必須至少有一個富。我希望能夠創建一個可以創建一個欄的單一表單,以及附加到該欄的儘可能多的foos。骨幹形式列表將是完美的,不幸的是我不知道如何使用嵌套模型來實現它。

謝謝。

回答

9

我以前從未使用過Backbone-Forms。但如果我想實現這個,而不使用這個插件,我會去這個方法。

我會有2模型和2集合。

模式

  • 酒吧

集合

  • 酒吧
  • FOOS

我會在酒吧模型解析方法,對每個模型創建一個集合。

查看

  • 的MainView(在酒吧集合通過)並呈現
  • BarsListView(創建自的MainView在酒吧集合傳遞)
  • BarView(巴型號通過)
  • FooListView(通過Foo集合)
  • FooView(通過Foo模型)

東西在這些線路。這只是一個粗略的例子

// 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

這是一個非常好的答案舒尚特,我開始賞金獎勵你的工作。 – Xeoncross

+0

看起來不錯,不得不贊同至強。 – thepk

+0

看起來像我給你一堆upvotes也。再次感謝! – Xeoncross