【问题标题】:How to treat nested collection events in Marionette?如何处理 Marionette 中的嵌套集合事件?
【发布时间】:2014-02-28 01:06:01
【问题描述】:

我有一个 API 资源,它为我提供了一个 users 列表,每个列表都有几个 items。层次结构是这样的:

- users
  - user
    - items
      - item
      - item
      - item
  - user
    - items
      - item
      - item
      - item

我想在单个页面上显示users 的列表,每个user 条目也在页面上显示其每个items

当单击这些items 中的任何一个时,它应该设置一个可通过整个users 集合访问的chosen 属性。

我很难让item 点击信息重新冒泡。我目前的实现是在创建一个单独的items集合才能呈现视图,但是我丢失了与其原始user model的连接,所以我在选择item时无法通知它。 p >

我的观点结构如下:

class List.Item extends Marionette.ItemView
  template: "path/to/template"

  events:
    "click" : "choose"

  choose: (e) ->
    # what to do?

class List.User extends Marionette.CompositeView
  collection: @collection
  template: "path/to/template"
  itemView: List.Item
  itemViewContainer: "span"

  initialize: ->
    @collection = new App.Entities.Items(@model.get("items"), parent: @)

  events:
    "click a" : "toggleChoose"

  @include "Chooseable"

class List.Users extends Marionette.CollectionView
  itemView: List.User

有没有更好的方法来构建这些集合或视图,或者有没有办法将信息从List.Item 视图传递到父视图List.User,然后传递到users 集合?

编辑

我尝试过骨干关系,但它似乎并没有完全满足我的需求。如果我在这里错了,请纠正我。

【问题讨论】:

    标签: backbone.js marionette backbone.js-collections


    【解决方案1】:

    您的 List.Item 应该包含它的当前模型以及触发选择时的所有属性。这样,您可以使用 List.Item 的模型值触发其他事件:

    choose(e) : ->
      trigger("mylistitem:choose", model)
    

    然后在别处监听事件:

    itemView.on("itemview:mylistitem:choose", ( childView, model ) -> {
     alert(model.get('..whatever..')
    }
    

    【讨论】:

    • 这里的问题是 Item 模型不包含对其原始用户的任何引用,那么如何在 user 或 users 集合上设置属性?
    • 看起来您只需要使用某种 userId 实例化您的项目模型(最简单的解决方案)。否则,看看遍历父集合:linkhere
    • 如何用 ID 实例化 Item 模型?这对我来说是最自然的解决方案,但我认为这是不可能的。
    • 将事件处理程序添加到集合的 add 函数 - 因此,每当将子项添加到集合中时,您都可以设置模型属性。 backbone.add
    【解决方案2】:

    实际上可以在 Backbone 中实例化 items 集合以引用父 user,反之亦然:

    class Entities.User extends Backbone.Model
      ...
      initialize: ->
        @items = new Entities.Items @get("items"),
          user: @
    
    class Entities.Items extends Backbone.Collection
      ...
      initialize: (models, options) ->
        @user = options?.user
    

    所以现在List.User CompositeView 可以将此信息传递给List.Item ItemView:

    class List.User extends Marionette.CompositeView
      collection: @collection
      ...
      initialize: ->
        @collection = @model.items
    

    有了这个,就可以直接从 ItemView 访问user

    class List.Item extends Marionette.ItemView
      ...
      events:
        "click" : "choose"
    
      choose: (e) ->
        e.preventDefault()
        user = @model.collection.user
        console.log "user: ", user
    

    从那里可以对user 及其集合采取任何必要的操作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-16
      • 2021-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多