Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/416.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用CompositeView呈现递归结构,同时使用木偶将每个模型封装在ItemView中_Javascript_Backbone.js_Recursion_Marionette - Fatal编程技术网

Javascript 使用CompositeView呈现递归结构,同时使用木偶将每个模型封装在ItemView中

Javascript 使用CompositeView呈现递归结构,同时使用木偶将每个模型封装在ItemView中,javascript,backbone.js,recursion,marionette,Javascript,Backbone.js,Recursion,Marionette,我将从一个明确的问题开始,然后解释: 如何将包含在复合视图中的模型正确封装到项目视图中 我的问题很简单,但我不能设法让一些好的工作。 我有一本笔记簿。 每个便笺都是一个Backbone.model,并有一个@subjects集合, 然后,我有一个主干.Collection来表示该树(其中@substands是一个实例) 我设置了一个基本的集合视图,其中组合视图作为项目视图。一切都很完美,我很高兴。此工作解决方案显示在第一段代码中 问题来了。在此基础上,我遇到了这个问题: 这对我的事件在哪里有意义

我将从一个明确的问题开始,然后解释:
如何将包含在
复合视图中的模型正确封装到
项目视图中

我的问题很简单,但我不能设法让一些好的工作。 我有一本笔记簿。 每个便笺都是一个Backbone.model,并有一个
@subjects
集合, 然后,我有一个主干.Collection来表示该树(其中@substands是一个实例) 我设置了一个基本的
集合视图
,其中
组合视图作为
项目视图
。一切都很完美,我很高兴。此工作解决方案显示在第一段代码中

问题来了。在此基础上,我遇到了这个问题: 这对我的事件在哪里有意义。起初,我只是简单地添加了唯一的选择器(将数据guid添加到我的html元素中,这样我就可以通过它来获取它们),它工作正常,尽管它已经变得“粗糙”。但其他类似的问题也出现了,所以我决定需要一个解决方案。 因此,我告诉myslef,让我们将每个模型封装在ItemView中,并使用复合视图递归地呈现它们。 但是这并不是世界上最好的

以下是我一开始的情况:

class Note.ModelView extends Marionette.CompositeView
  template: "note/noteModel"
  id: "note-item"
  itemViewContainer: ".note-descendants"
  ui:
    noteContent: ".noteContent"
  events:
    "keypress .noteContent": "createNote"
    "click .destroy": "deleteNote"
  # ...
  initialize: ->
    @collection = @model.descendants
  # ...

class Note.CollectionView extends Marionette.CollectionView
  id: "note-list"
  itemView: Note.ModelView
  initialize: ->
    @listenTo @collection, "sort", @render
现在,我在一个新的ItemView中传输了所有属于渲染模型的内容

  class Note.ModelView extends Marionette.ItemView
    template: "note/noteModel"

    ui:
      noteContent: ".noteContent"
    events: ->
      guid = @model.get 'guid'
      events = {}
      events["keypress #noteContent#{guid}"] = "createNote"
      events["blur #noteContent#{guid}"] = "updateNote"
      events["click #destroy#{guid}"] = @triggerEvent 'deleteNote'

    initialize: ->
      @bindKeyboardShortcuts()
      @listenTo @model, "change:created_at", @setCursor

  class Note.TreeView extends Marionette.CompositeView
    template: "note/parentNote"
    itemView: Note.ModelView

    initialize: ->
      @collection = @model.descendants
      @listenTo @collection, "sort", @render
      _.bindAll @, "renderItem"
    renderItem: (model) ->
      if model.get('parent_id') is 'root'
        itemView = new Note.ModelView model: model
        itemView.render()
        @$el.append itemView.el
    onRender: ->
      @collection.each this.renderItem
      @renderItem @model
    appendHtml: (collectionView, itemView) ->
      @model.descendants.each (note) =>
        iv = new Note.ModelView model: note
        iv.render()
        @.$('.note-descendants').append iv.el


  class Note.CollectionView extends Marionette.CollectionView
    id: "note-list"
    itemView: Note.TreeView
    initialize: ->
      @listenTo @collection, "sort", @render
以及noteMode模板(parentNote现在只是一个空模板)

UN
桌棋类游戏
{{{indent}}{{{title}}}
#这就是我放孩子们笔记的地方
所以这几乎是可行的。但是它很粗糙而且。。嗯,还是不太管用。我已经阅读了所有的文档,我已经阅读了这两个链接,但我仍然觉得我遗漏了一些重要的细节

作为一个答案,我在寻找的是任何提示或任何常用的方法来管理这个木偶。我真的在寻找一些干净的东西,因为这将是构建应用程序的一个角度部分。
也许我也找错地方了?什么都欢迎!!多谢各位

祝大家晚上过得愉快。
谢谢您的时间。

我将用不同的语言向您解释德里克·贝利在您引用的博文中已经说过的话

视图

您需要两个视图才能完成此操作

第一个是“母视图”,它是最外层的视图,包含递归结构作为其子节点。这可以是木偶图.CollectionView或木偶图.CompositeView

第二个视图是递归视图,这意味着它需要是一个木偶。通过不指定“itemView”属性,可以使Marionette.CompositeView递归。在缺少itemView属性的情况下,Marionette.CompositeView将使用自身来呈现给定集合的模型

收藏

您需要一个集合,它可以是一个主干。嵌套主干。集合的集合,也可以是一个包含深度嵌套哈希的主干。集合。在后一种情况下,您不必忘记将简单哈希值转换为Backbone.Collections,然后将它们交给一个Marionette.CompositeView(如下在RecursiveView的initialize()方法中所做)

将所有内容放在一起

var RecursiveView = Marionette.CompositeView.extend({
    template: '#someTemplate',
    initialize: function () {
        this.collection = this.model.get('children')
    }
});

var MotherView = Marionette.CollectionView.extend({
    itemView: RecursiveView,
    collection: new Backbone.Collection([{key: 'value', children: [{}, {}, {}]}])
});
问题:事件冒泡

很自然,DOM事件现在会冒泡,所以下面的代码

var RecursiveView = Marionette.CompositeView.extend({
    events: {
        'click button': someCallback
    }
});
将是它引用的视图及其所有子体的事件的总括

解决此问题的最简单方法是使用直接后代css选择器
,例如:

var RecursiveView = Marionette.CompositeView.extend({
    events: {
        'click >button': someCallback
    }
});
如果这还不够,一个有效的解决方案是防止自动事件冒泡,例如

var RecursiveView = Marionette.CompositeView.extend({
    events: {
        'click button': function (event) {
            event.stopPropagation();
            // or event.stopImmediatePropagation() depending on your use case
            // cf. http://stackoverflow.com/a/5299841/899586 and 
        }
    }
});

工作演示-详细信息-感谢您链接问题中已有的链接!。。这个代码和我发布的第一个代码有什么区别?没有一个我有这个工作,非常感谢。我正在寻找一种方法来封装生成的html,这样最里面的视图只能访问它的html,而不能访问整个层次结构的html。好的,对不起,误读了你的文章,真的错了。为什么不添加直系子体选择器
,以便只检查直系子体上发生的DOM事件?如果这对您来说还不够的话,我宁愿攻击事件传播方面的问题:停止递归视图中的事件冒泡!因此,你提出的解决方案确实有效,它们实际上正是我目前所拥有的。问题是,我发现这个问题很棘手,我想在ItemView中清晰地封装所有内容。但是通过对代码的处理,我得出了这样的结论:这可能不太可能,因为这样做显然会丢失递归性。然后你会发现自己正在重新实现它。。你对那个方向有什么暗示吗?如果没有其他问题,我会记下你的答案,尽管它实际上对我没有帮助,但你确实花了时间!问题是,事件冒泡不是在backbone.view/marionete.view范围内发生的,而是纯粹在DOM本身内发生的。主干网/木偶网一侧没有发生您可以禁用的事件调度。这里冒泡的事件纯粹是DOM的一个“特性”。因此,您必须在DOM中构建一个平面层次结构,因为事件只会向其父级而不是其兄弟级冒泡。然后,您将需要适当的CSS或JS代码来创建视觉错觉,即所讨论的DOM元素实际上处于视觉层次结构中……:)因此,stopPropagation()是中断DOM标准功能的“黑客”。在代码中的其他地方,这确实可以被认为是骇客的、罪恶的,您可能期望事件会冒泡。因此,第一个解决方案是可怕的
var RecursiveView = Marionette.CompositeView.extend({
    events: {
        'click button': function (event) {
            event.stopPropagation();
            // or event.stopImmediatePropagation() depending on your use case
            // cf. http://stackoverflow.com/a/5299841/899586 and 
        }
    }
});