在BackBone js中渲染视图时调用javascript.渲染后回调

calling javascript on rendering views in BackBone js. post-render callback?

本文关键字:调用 javascript 回调 视图 BackBone js      更新时间:2023-09-26

看,主干视图渲染调用:

render: function() {
  $(this.el).html(this.template({title: 'test'}));  //#1
  this.renderScatterChart();
  return this;
},

因此,我在#1调用标准渲染。然后,我调用一个方法[这次,它是一个用于绘制lib的包装器]来查找div。div由render调用呈现。但在这一点上,它还没有附加到DOM(对吗?)。因此图表调用不幸终止。

这是什么模式?我很想听到有一个渲染后回调。我已经尝试了一些技巧,有时我会让图表发挥作用,但事件不会绑定。

对于这类事情,我通常的方法是使用超时为零的setTimeout,以安排在浏览器再次获得控制权时发生一些事情。试试这个:

render: function() {
    $(this.el).html(this.template({title: 'test'}));
    var _this = this;
    setTimeout(function() {
        _this.renderScatterChart();
    }, 0);
    return this;
}

或者,如果renderScatterChart已经绑定到适当的this:

render: function() {
    $(this.el).html(this.template({title: 'test'}));
    setTimeout(this.renderScatterChart, 0);
    return this;
}

如果你想更明确地说明你在做什么,你也可以使用_.defer

推迟_.defer(function, [*arguments])

延迟调用函数,直到清除当前调用堆栈,类似于使用延迟为0的setTimeout

所以你也可以这样做:

// Assuming that `renderScatterChart` is bound to the appropriate `this`...
render: function() {
    $(this.el).html(this.template({title: 'test'}));
    _(this.renderScatterChart).defer();
    return this;
}
// or if it isn't bound...
render: function() {
    $(this.el).html(this.template({title: 'test'}));
    var _this = this;
    _(function() {
        _this.renderScatterChart();
    }).defer();
    return this;
}

我知道这是有答案的,但我想分享一下。Underscore js已经用_.dedefer函数为您介绍了这一点。

render: function() {
    $(this.el).html(this.template({title: 'test'}));  //#1
    _.defer( function( view ){ view.renderScatterChart();}, this );
    return this;
},

根据Undercore文档,这实际上与公认的解决方案是一样的。

这是因为在将.el插入DOM之前运行了render。检查我的不言自明的代码(在包含Backbone.js的空白页中运行):

function someThirdPartyPlugin(id){
   if( $('#' +id).length ===0  ){
    console.log('Plugin crashed');
   }else{
    console.log('Hey no hacks needed!!!'); 
   }
}
var SomeView = Backbone.View.extend({
    id : 'div1',
    render : function(){
      this.$el.append("<p>Hello third party I'm Backbone</p>");
      someThirdPartyPlugin( this.$el.attr('id') );
      return this;
  }
}); 
var SomeView2 = Backbone.View.extend({
    id : 'div2',
    render : function(){
      this.$el.append("<p>Hello third party I'm Backbone</p>");
      someThirdPartyPlugin( this.$el.attr('id') );
      return this;
  }
}); 
var myView1 = new SomeView();
$('body').append( myView1.render().el );
var myView2 = new SomeView2();
$('body').append( myView2.el );
myView2.render();

您可以这样做(如果renderSatterChart在"jQuery ized"对象上操作):

render: function() {
  this.$el.html(this.template({title: 'test'}));  //#1
  this.$el.renderScatterChart();
  return this;
},

(这不是实际的DOM元素…)

遇到了与您相同的问题。。。高图表。我使用的是Backbone.LayoutManager,最后破解了添加postRender回调的代码。我很想把它作为Backbone.js 的一部分

如果你不想使用setTimeout破解,我认为这种方式更"正常":

只需将$el元素传递给需要操作render()添加的元素的函数,就可以对$el进行DOM操作。

这个问题已经得到了回答,但为了将来参考,我已经遇到过几次这个问题。我通过添加自定义事件解决了这个问题,在这种情况下,它可能类似于

render: function() {
  $(this.el).html(this.template({title: 'test'}));  //#1
  this.on('someView:append', function() {
      this.renderScatterChart();
  }, this);
  return this;
}

然后,当我将元素附加到DOM时,我会像一样触发它

myView.trigger('someView:append');

现在,这肯定不是一个好的解决方案。您正在将触发此事件的响应性添加到将渲染视图附加到DOM的任何内容中。根据代码的结构,它可以更好也可以更糟。再说一遍,我只是把这个作为未来的参考和替代。

更多信息:http://backbonejs.org/#Events

应该这样做:

render: function() {
  Marionette.ItemView.prototype.render.apply(this, arguments);
  your code ...
}

带有提线木偶的示例,但该想法适用于主干视图以及