在Backbone渲染方法中调用jQuery插件

我在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(); }, 

我宁愿不这样做,因为插件是视图的一部分,而不是路由器,所以在动作中调用它是没有意义的。 有一个更好的方法吗?

贝特这样做:

 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; }, 

我遇到了一个类似的问题,设置了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的新手,请随时发表评论。

只能通过在render函数中指定jQuery的上下文来使我的jQuery插件工作:

  render: function () { $(this.el).html(this.template(this.model.toJSON())); $('#email1dropdown', this.el).dropdownify(); return this; }, 

我已经通过在我的视图中添加了一个loadPlugins方法来“解决”了这个问题,所以我可以在动作中渲染后执行myView.loadPlugins() 。 它并不理想,但它确实有效。


编辑:嗯,我从马的嘴里听说,看起来我不能在元素被添加到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 }, 

我遇到了类似的问题,但在我的情况下,即使上述解决方案也无效,因为尚未将父视图添加到DOM中。

坚持使用父视图将子项添加到DOM的约定,在render方法中执行loadPlugins()不起作用。

这就是我所做的。 这有点像hacky但可以提供帮助,具体取决于您在整个层次结构中管理视图的方式:

 render: function() { var self = this; setTimeout(function() { $(self.el).setupPlugin(); }, 0); return this; } 

使用setTimeout为0允许当前调用堆栈完成,因此在调用timeout函数时,视图及其所有父项都已添加到DOM中。 (如果你坚持上面提到的惯例)。