我在Backbone中有一个基本上像这样的渲染方法:
render: function () {
$.tmpl(this.template, attrs).appendTo(this.el);
return this;
},
从路由器操作调用:
action: function () {
$('#container').empty();
$('#container').append(myView.render().el);
},
现在,我想在此视图中的label
元素上应用插件。我的第一个想法是在render
内调用插件:
render: function () {
$.tmpl(this.template, attrs).appendTo(this.el);
this.$('label').inFieldLabels();
return this;
},
但这不起作用(我假设这是因为该元素尚未添加到DOM中)。如果我在路由器操作中调用插件,它 工作:
action: function () {
$('#container').empty();
$('#container').append(myView.render().el);
myView.$('label').inFieldLabels();
},
我宁愿不这样做,因为插件是视图的一部分,而不是路由器,所以在动作中调用它是没有意义的。有更好的方法吗?
答案 0 :(得分:5)
贝特这样做:
action: function () {
var container = $('#container');
container.empty();
myView.render(container);
},
render: function (container) {
$(this.el)
.append($.tmpl(this.template, attrs))
.appendTo(container);
$('label', this.el).inFieldLabels();
return this;
},
答案 1 :(得分:5)
我遇到了类似的问题,设置了jQuery Tools Tooltip插件。但我有一个非常不同的方法,可以很好地工作:在视图上触发自定义事件。据我所知,Backbone中没有“插入dom”事件,所以我自己就做了。我不使用路由器,但上面修改过的代码看起来像这样:
// In the router:
action: function () {
var container = $('#container');
container.append(myView.render().el));
myView.trigger('rendered');
},
// In the view:
initialize: function() {
this.bind('rendered', this.afterRender, this);
},
render: function (container) {
$(this.el).append($.tmpl(this.template, attrs))
return this;
},
afterRender: function() {
$('label', this.el).inFieldLabels();
}
我认为优点是视图不知道它的容器。缺点是它就像一行或两行代码。但是如果你需要设置很多插件或做更多需要元素在DOM中的东西,那么它就能很好地工作(并且它会保持逻辑分离)。
我实际上喜欢@ Skilldrick将容器传递给视图的方法,但我仍然觉得让父视图负责插入子视图是有意义的。我是Backbone的新手,所以请随时发表评论。
答案 2 :(得分:2)
我能够通过在渲染函数中指定jQuery的上下文来使我的jQuery插件正常工作:
render: function () {
$(this.el).html(this.template(this.model.toJSON()));
$('#email1dropdown', this.el).dropdownify();
return this;
},
答案 3 :(得分:0)
我已经通过在我的视图中添加loadPlugins
方法解决了这个问题,因此我可以在渲染操作后执行myView.loadPlugins()
。它并不理想,但它确实有效。
编辑:好吧,我heard from the horse's mouth看起来在将元素添加到DOM之前我无法应用插件,所以我可以像上面那样做(使用loadPlugins
)或者我可以修改代码,以便在render
方法中将元素添加到DOM中。希望这有助于处于类似位置的人。
以下是我现在的做法:
//in router
action: function () {
var myView = new MyView({
el: '#container'
});
}
//in view
render: function () {
$.tmpl(this.template, attrs).appendTo(this.el); //this now appends to the DOM
this.loadPlugins();
return this;
},
loadPlugins: function () {
this.$('label').inFieldLabels();
//and other plugins
},
答案 4 :(得分:0)
我遇到了类似的问题但在我的情况下,即使上述解决方案也无效,因为父视图尚未添加到DOM中。
坚持让父视图将子项添加到DOM的约定,在render方法中执行loadPlugins()不起作用。
这就是我所做的。这有点像hacky但可以提供帮助,这取决于你在整个层次结构中管理你的观点的方式:
render: function() {
var self = this;
setTimeout(function() {
$(self.el).setupPlugin();
}, 0);
return this;
}
使用setTimeout为0允许当前调用堆栈完成,因此在调用超时函数时,视图及其所有父项都已添加到DOM中。 (如果你坚持上述惯例。)