Backbone on Rails如何将模型添加到不同视图的集合中?

时间:2013-02-24 10:15:57

标签: ruby-on-rails ruby-on-rails-3 backbone.js coffeescript

我正在使用Rails 3backbone-on-rails gem开发Rails应用。

我有一个显示ProductTypes的骨干路线。它有一个列表的骨干视图和一个窗体视图,因此usar可以添加新的ProductTypes。

一切正常,但是当我尝试将创建的模型从表单视图添加到列表视图上的集合时。我不知道如何连接两个视图。

这是我的路线:

class Newgvbtool.Routers.ProductTypes extends Backbone.Router
  routes:
    'companies/:company_id/product_types': 'index'

  initialize: ->
    @container = $('#product-types-view')
    @company_id = @container.data 'company_id'
    @collection = new Newgvbtool.Collections.ProductTypes([],{ company_id: @company_id })
    @collection.fetch()

  index: (company_id) ->
    view = new Newgvbtool.Views.ProductTypesIndex(collection: @collection)
    @container.append view.render().el

    newModel = new Newgvbtool.Models.ProductType({ company_id: @company_id })
    editView = new  Newgvbtool.Views.ProductTypeEdit model: newModel
    @container.append editView.render().el

她是我的模特:

class Newgvbtool.Models.ProductType extends Backbone.Model
  initialize: (model)-> 
    @company_id = model.company_id
    @id = model.id
  url: ()->
    "/api/companies/#{@company_id}/product_types/" + (@id || '')

以下是我的观点:

# Collection view
class Newgvbtool.Views.ProductTypesIndex extends Backbone.View

  template: JST['product_types/index']

  events: ->

  initialize: ->
    @collection.on 'reset', @render
    @collection.on 'add', @appendItem
    @collection.on 'remove', @removeItem

  render: =>
    $(@el).html @template()
    @collection.each @appendItem
    @

  appendItem: (model)=>
    view = new Newgvbtool.Views.ProductType model: model
    $('#product-types tbody').append(view.render().el)

  removeItem: (model)=>
    $('#product-types tbody').find("tr[data-id=#{model.get('id')}]").remove()


 #Item view
 class Newgvbtool.Views.ProductType extends Backbone.View

  template: JST['product_types/product_type']
  tagName: 'tr'

  events:
    'click .delete-item': 'deleteItem'

  initialize: ->
    @model.on 'highlight', @highlight
    @model.on 'change', @render

  render: =>
    $(@el).attr('data-id', @model.get('id')).html @template( model: @model)
    @

  highlight: =>
    @$('td').effect 'highlight', 1000

  deleteItem: ->
    @model.destroy(
      wait: true
    ) if confirm "Are you sure?"

#Form view
class Newgvbtool.Views.ProductTypeEdit extends Backbone.View

  template: JST['product_types/edit']

  render: =>
    $(@el).html @template( model: @model )
    @

  events: ->
    'submit #product-type-form': 'createProductType'

  createProductType: (e) ->
    e.preventDefault()

    attributes = $(e.currentTarget).serializeForm()['product_type']

    @model.save attributes,
      wait: true
      success: (model)->
        $('#product-type-form')[0].reset()
        model.trigger('highlight')

有没有办法在表单视图中保存新模型时我可以将该模型实际添加到主集合中,以便触发添加事件并在集合视图中显示此新模型?

在更新项目的情况下,我可以进行相反的操作,将列表中选择的模型设置为表格,以便更新并将这些更改反映到集合的视图中吗?

非常感谢你!

1 个答案:

答案 0 :(得分:0)

我建议您在应用程序上创建一个事件聚合器,这样您就可以轻松地在视图上触发自定义事件,并让另一个事件的侦听器对其做出反应。

这是Derick Bailey的link帖子,他解释了这是如何工作的,并提供了一些如何实现它们的想法。

如果您使用主对象来实例化您的应用程序,您可以执行以下操作:

window.App =
 Models: {}
 Collections: {}
 Views: {}
 Routers: {}

 initialize: ->
  @vent = _.extend({}, Backbone.Events)
  # More code here

$(document).ready ->
  App.initialize() 

然后,App.vent将成为您的事件聚合器,您可以触发这样的事件:

App.vent.trigger "model:add:success", @model

在此触发“model:add:success”传递模型“@model”。然后你可以用其他地方捕捉它:

initialize: ->
  App.vent.on "model:add:success", @appendModel, this