Backbone.Marionette的onRender回调在视图在浏览器中渲染之前就触发了?

29

设置

我有一个Backbone.Marionette.ItemView,它渲染一些内容。当内容被渲染时,我想应用一个jQuery插件,将视图的一部分变成带有滚动条的容器。

滚动条完全是用javascript实现的,在初始化时必须检查滚动容器的高度以及容器内部内容的高度。

如果内容高度大于容器高度,则应启用滚动条。

问题

虽然这听起来很简单,但我遇到了一个奇怪的问题:

如果我直接在onRender回调函数中初始化滚动条插件,它似乎认为.scroll-container元素的高度为0,最大高度为0。

但是,如果我将初始化代码包裹在0毫秒的超时函数中,一切都可以正常工作,jQuery正确返回.scroll-container元素的高度属性,滚动条插件也能正常工作。

代码

onRender: function() {
  var that = this;
  setTimeout(function() {
    that.onLayout();
    var $scrollContainer = that.$el.find('.scroll-container'), 
        scrollPane = new ScrollPane($scrollContainer, {
          maxHeightProperty: 'maxHeight',
          scrollUpButton: false,
          scrollDownButton: false
        });
  }, 0);
},

问题

我假设问题出现在浏览器没有完全渲染新插入的HTML代码时,onRender回调被执行。

这个假设正确吗?如果是这样,那么在正常情况下使用0毫秒的超时来解决这个问题是否可靠?

1个回答

41

由于涉及到 DOM,所以onRender不能满足你的需求。这个回调函数在视图被渲染后启动,但是不能保证视图的 el 已经添加到 DOM 中。实际上,可以安全地假设相反的情况 - 它还没有被添加。

如果你正在使用 Marionette 的Region来展示视图,则可以在你的视图中实现一个onShow方法。这个方法会在区域将视图添加到 DOM 后由区域调用。它是专门为处理这种情况而实现的。

关于这个问题的更多信息以及关于一般使用 jQuery 插件的内容,请参阅这篇博客文章:http://lostechies.com/derickbailey/2012/02/20/using-jquery-plugins-and-ui-controls-with-backbone/


太棒了,谢谢!就是这样了。看起来比0毫秒的超时好多了! - Ruben Vreeken
2
请注意,如果您正在使用包含区域(例如布局)的Marionette视图,则它还将具有一个“onShow”方法,您可以将其挂钩。 - cmcculloh
1
onShow刚刚为我节省了大量时间!谢谢! - streetlight
@Derick - 如果我在onShow中附加一个事件监听器(使用$('.selector').on('...),那么我应该在onClose中解除绑定吗? - ragulka
2
只要在视图实例上调用closeremove方法,当视图关闭时,DOM事件将自动清除。DOM事件的清理内置于Backbone.View的“remove”方法中。 - Derick Bailey
你也可以使用 onAttach,它会在 onShow 之后触发。 - Yazan Rawashdeh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接