重新渲染&将子视图的HTML附加到DOM似乎不会重新应用子视图的事件

时间:2013-01-02 13:51:35

标签: backbone.js marionette

the Marionette docs for CompositeView中,它描述了覆盖appendHTML以自定义目标,应使用jQuery的append添加每个itemView的HTML。

使用类似的思路,如果我有两个ItemView个对象,则ParentChild以及Parent的模板都有一个空目标{{ 1}}我想在其中注入<div class="target"></div>的模板。我可以在Child中使用jQuery的htmlonRender来执行此操作。

Parent生命的整个过程中,我想用其他东西清除或替换Parent的内容。如果我以后想要将.target重新呈现为Child (因为它可能会根据自第一次渲染后的用户交互呈现不同的模板),我可以使用相同的逻辑:

  1. 呈现.target模板
  2. 使用jQuery的html
  3. Child的内容设置为.target的{​​{1}}

    问题是,一旦发生Child的第二次呈现,el视图中的任何事件似乎都会丢失。

    以下是我所描述的具体例子:

    HTML

    Child

    Javascript

    Child

    首先点击<script type="template" id="parent"> <p><a class="re-render" href="javascript://">Re-Render</a></p> <div class="target"></div> </script> <script type="template" id="child"> <p><a href="javascript://">The Link</a></p> </script> <div id="main"></div> 中的链接效果很好。在var Views = {}; Views.Child = Backbone.Marionette.ItemView.extend({ template: '#child', events: { 'click a': 'changeBg' }, changeBg: function() { this.$el.css('background-color', '#'+Math.floor(Math.random()*16777215).toString(16)); } }); Views.Parent = Backbone.Marionette.ItemView.extend({ template: '#parent', childView: undefined, ui: { target: '.target' }, events: { 'click .re-render': 'onRender' }, initialize: function() { this.childView = new Views.Child(); }, onRender: function() { this.childView.render(); this.ui.target.html(this.childView.el); this.childView.$el.css('background-color', 'transparent'); } }); var App = new Backbone.Marionette.Application(); App.addRegions({ mainRegion: "#main" }) App.mainRegion.show(new Views.Parent()); 中点击重新渲染后,Child点击事件永远不会重新应用于新呈现的Parent模板版本。 如何确保每次呈现Child时都会重新应用Child模板的事件?

    您可以为 here 找到一个jsFiddle。

1 个答案:

答案 0 :(得分:1)

您应该在子视图重新渲染后调用.delegateEvents()

onRender: function() {
  this.childView.render();
  this.ui.target.html(this.childView.el);
  this.childView.delegateEvents();
  this.childView.$el.css('background-color', 'transparent');
}

这是如何在vanilla Backbone中解决它。我不知道Backbone.Marionette是否有另一种处理问题的方法,但在Marionette术语中,您可以将delegateEvents调用添加到子视图的onRender方法中以封装重新呈现。

Views.Child = Backbone.Marionette.ItemView.extend({
    //...
    onRender: function() {
        this.delegateEvents();
    }
});