【问题标题】:Backbone on Rails how to add a model to a collection from different views?Rails 上的 Backbone 如何将模型添加到来自不同视图的集合中?
【发布时间】:2013-02-09 15:18:41
【问题描述】:

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

我有一个显示 ProductTypes 的主干路由。它有一个用于列表的主干视图和一个用于表单的视图,因此 usar 可以添加新的 ProductType。

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

这是我的路线:

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')

有没有办法,当一个新模型保存在表单视图中时,我实际上可以将该模型添加到主集合中,以便触发添加事件并且这个新模型出现在集合视图中?

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

非常感谢您!

【问题讨论】:

  • 您可以在初始化模型时为模型提供对集合的引用。这样,模型可以在用户保存它时将自己添加到集合中。
  • 您可以设置一个全局事件“productType:save”并将您的收藏绑定到它。在模型保存时触发该事件。但如果模型属于多个集合,这是一个很好的策略。我仍然希望您在调用表单事件的视图中执行此操作。创建模型,保存它,将其添加到集合中
  • 感谢您的回复!

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


【解决方案1】:

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

这是发给 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”的“model:add:success”。然后你可以在其他地方捕捉到它:

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

【讨论】:

  • 这是一个非常好的解决方案!
猜你喜欢
  • 2013-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多