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

Ski*_*ick 14 jquery jquery-plugins backbone.js

我在Backbone中有一个渲染方法基本上是这样的:

render: function () {
  $.tmpl(this.template, attrs).appendTo(this.el);
  return this;
},
Run Code Online (Sandbox Code Playgroud)

从路由器动作调用:

action: function () {
  $('#container').empty();
  $('#container').append(myView.render().el);
},
Run Code Online (Sandbox Code Playgroud)

现在,我想label在此视图中的元素上应用插件.我的第一个想法就是调用插件render:

render: function () {
  $.tmpl(this.template, attrs).appendTo(this.el);
  this.$('label').inFieldLabels();
  return this;
},
Run Code Online (Sandbox Code Playgroud)

但这不起作用(我假设这是因为该元素尚未添加到DOM中).如果我在路由器操作中调用插件,它确实有效:

action: function () {
  $('#container').empty();
  $('#container').append(myView.render().el);
  myView.$('label').inFieldLabels();
},
Run Code Online (Sandbox Code Playgroud)

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

ant*_*_Ti 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;
},
Run Code Online (Sandbox Code Playgroud)


Mat*_*eon 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();
}
Run Code Online (Sandbox Code Playgroud)

我认为优点是视图不知道它的容器.缺点是它就像一行或两行代码.但是如果你需要设置很多插件或做更多需要元素在DOM中的东西,那么它将运行良好(并且它保持逻辑分离).

我实际上喜欢@ Skilldrick将容器传递给视图的方法,但我仍然觉得让父视图负责插入子视图是有意义的.我是Backbone的新手,请随时发表评论.


Ski*_*ick 0

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


编辑:嗯,我从马嘴里听说,看起来我无法在将元素添加到 DOM 之前应用该插件,所以我可以按照上面的方法(使用loadPlugins)进行操作,或者我可以修改代码,以便元素在该方法中添加到 DOM 中render。希望这对处于类似位置的人有所帮助。

我现在是这样做的:

//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
},
Run Code Online (Sandbox Code Playgroud)