当父母第二次出现时,Marionette不会渲染子视图

时间:2014-11-04 08:05:57

标签: javascript backbone.js marionette

我想在应用中重复使用视图(之前打开的屏幕),但区域内容会消失。如何防止木偶这样做?

  var app = new Backbone.Marionette.Application();
  window.app = app;

  app.addRegions({
    root: 'body'
  });

  var View1 = Marionette.LayoutView.extend({
    template: _.template('<div>View1<div class="sub"></div></div>'),
      regions: {
        sub: '.sub'
      }
  });

  var View2 = Marionette.ItemView.extend({
    template: _.template('<div>View2</div>')
  });

  var SubView = Marionette.ItemView.extend({
    template: _.template('<div>SubView</div>')
  });

  var view1 = new View1();
  var view2 = new View2();
  var subView = new SubView();

  app.root.show(view1, { preventDestroy: true });
  view1.sub.show(subView, { preventDestroy: true });

  setTimeout(function() {
    app.root.show(view2, { preventDestroy: true });
    setTimeout(function() {
      app.root.show(view1, { preventDestroy: true });
    }, 500);
  }, 500);

或小提琴http://jsfiddle.net/ndr7262y/

1 个答案:

答案 0 :(得分:1)

因此,preventDestroy不会阻止区域内的子视图仅被实际区域本身销毁。木偶的设计试图鼓励破坏视图并重新初始化它们,以便妥善处理清理工作。绕过这个问题的另一种方法是在显示视图时监听,然后显示子

app.listenTo(view1, "show", function () {
          view1.sub.show(subView)
});

唯一的问题是子视图仍然被销毁,因此您可以覆盖subView的destroy方法以不破坏视图,这有点棘手以保持跟踪,因为现在您将不得不手动确保正确应用/删除绑定

  var SubView = Marionette.ItemView.extend({
      template: _.template('<div>SubView</div>'),
      destroy: function () {

          if (this.isDestroyed) {
              return;
          }

          var args = [].slice.call(arguments);

          this.triggerMethod.apply(this, ['before:destroy'].concat(args));

          // mark as destroyed before doing the actual destroy, to
          // prevent infinite loops within "destroy" event handlers
          // that are trying to destroy other views
          this.isDestroyed = false;
          this.triggerMethod.apply(this, ['destroy'].concat(args));

          // unbind UI elements????? well its not beng destoryed so probably don;t wantto do this
          //unless you manually handle rebind the events
          //this.unbindUIElements();
          return this;
      }
  });

最终结果http://jsfiddle.net/ndr7262y/2/

但是这里更好的方法是在显示视图1时重新显示子视图

app.listenTo(view1, "show", function () {
           var subView = new SubView();
          view1.sub.show(subView)
});

现在你不必担心清理或覆盖destroy方法。 http://jsfiddle.net/ndr7262y/4/