Cri*_*hai 1 javascript coffeescript backbone.js backbone-views
我正在研究一个Backbone.View
应该将集合呈现为可滚动列表的集合.
作为初始渲染的一部分,我需要访问一些布局属性(例如clientWidth
),这些属性仅在渲染视图后才可用.
我的问题是,我如何知道何时将视图添加到DOM?
使用a Backbone.View
通常有两种方法将视图附加到DOM:
创建视图>渲染>附加它:
view = new MyList().render()
$('#dummy').append(view.$el)
Run Code Online (Sandbox Code Playgroud)创建视图并就地呈现它:
new MyList({el: '#dummy'}).render()
Run Code Online (Sandbox Code Playgroud)注意:我知道(1)和(2)不是完全等价的,这不是重点.
让我们考虑我的列表定义如下:
class MyList extends Backbone.View
render: ->
@$el->html( ... )
@
layout: ->
max = $el.scrollWidth - $el.clientWidth
# ... disable / enable scrolling arrows based on max ...
Run Code Online (Sandbox Code Playgroud)
在MyList附加到DOM之后,您如何确保调用layout()?
我遇到过这个问题,有些模式可以提供帮助.Backbone为您提供工具,但不会告诉您如何使用它们.在使用它时建立良好的模式非常重要.我使用了两种不同的模式来帮助解决这个问题.
1)根据应用程序的工作方式,在渲染方法并将其附加到DOM后,始终可以轻松或难以确保在视图上调用attached()
方法或触发attached
事件.就我而言,这很简单,因为我创建了一个架构,我可以在一个中心位置处理它.
2)如果你总是在渲染之后立即将你的元素附加到DOM - 特别是在渲染之后的任何时间,而不是在异步回调中通过这样做来延迟附加,那么在你的render()函数中你可以将调用推迟到layout()
或者需要运行什么被附上后 像这样:
var MyList = Backbone.View.extend({
render: function() {
/* rendering logic goes here */
// Notice that the timeout is 0 - you can actually not even pass this argument
// but I wanted to emphasize that there is no delay given.
setTimeout(this.layout, 0);
return this;
},
layout: function() {
// This code won't be run until after this.el is attached to the DOM
}
});
var view = new MyList().render();
$('#dummy').append(view.$el);
Run Code Online (Sandbox Code Playgroud)
Javascript始终是单线程的.I/O可以异步完成,但实际需要JS引擎时间的任何东西都不能与其他JS代码并行运行.当您在setTimeout()
没有最后一个参数或其值的情况下调用时0
,它将基本上将其排队,以便在当前执行的代码完成后尽快运行.
如果你遵循一种在调用后很快就会附加到DOM的模式render()
- 在当前正在执行的代码完成运行之前的任何时间,并将控制权返回给JS引擎来运行接下来排队的任何内容,你可以利用这一事实.当运行排队的函数setTimeout(func, 0)
运行时,您就可以知道您的视图已附加到DOM.请注意,这与事情是_.defer()
一样的,但我想为您解释一下.
再次,模式是非常重要的建立.如果你从来没有保持一致并且没有在你的应用程序中建立模式,你就没有任何保证,你就失去了依赖这种机制的能力 - 以及你可能能够建立的其他机制.希望这可以帮助!
归档时间: |
|
查看次数: |
1904 次 |
最近记录: |