Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/384.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/svn/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在主干js中呈现视图时调用javascript。渲染后回调?_Javascript_View_Backbone.js - Fatal编程技术网

在主干js中呈现视图时调用javascript。渲染后回调?

在主干js中呈现视图时调用javascript。渲染后回调?,javascript,view,backbone.js,Javascript,View,Backbone.js,请看,主干视图渲染调用: render: function() { $(this.el).html(this.template({title: 'test'})); //#1 this.renderScatterChart(); return this; }, 因此,我将标准渲染称为#1。然后,我调用一个方法[这次,它是一个图表库的包装器]来查找div。但是在这一点上,它还没有连接到DOM(对吗?)。因此,图表调用不幸地死去 这种模式是什么?我希望听到有一个渲染后回调。我已经尝试

请看,主干视图渲染调用:

render: function() {
  $(this.el).html(this.template({title: 'test'}));  //#1
  this.renderScatterChart();
  return this;
},
因此,我将标准渲染称为#1。然后,我调用一个方法[这次,它是一个图表库的包装器]来查找div。但是在这一点上,它还没有连接到DOM(对吗?)。因此,图表调用不幸地死去


这种模式是什么?我希望听到有一个渲染后回调。我已经尝试过一些解决方法,有时我会让图表正常工作,但事件不会绑定。

我通常的做法是在超时为零的情况下,一旦浏览器再次获得控制权,就安排一些事情发生。试试这个:

render: function() {
    $(this.el).html(this.template({title: 'test'}));

    var _this = this;
    setTimeout(function() {
        _this.renderScatterChart();
    }, 0);

    return this;
}
或者,如果
renderScatterChart
已绑定到相应的
,则此

render: function() {
    $(this.el).html(this.template({title: 'test'}));
    setTimeout(this.renderScatterChart, 0);
    return this;
}
如果您想更明确地了解自己的活动,也可以使用:

延迟
延迟(函数,[*参数])

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

所以你也可以这样做:

// 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;
}
您可以这样做(如果renderSactterChart在“jQuery-ized”对象上运行):


(这不是实际的DOM元素…

与highcharts的问题相同。我使用的是Backbone.LayoutManager,最后修改了代码以添加postRender回调。我很想将此作为Backbone.js的一部分,这个问题已经得到了回答,但为了将来的参考,我已经遇到过好几次了。我通过添加自定义事件解决了这个问题,在本例中,它可能类似于

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的任何内容中。取决于代码的结构,它可以更好或更差。再一次,我只是将此作为未来的参考和替代


更多信息:

我知道答案是肯定的,但我想与大家分享一下。下划线js通过ux.defer函数为您提供了这一功能

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

根据下划线文档,这实际上与公认的解决方案相同。

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

函数someThirdPartyPlugin(id){
if($('#'+id).length==0){
log(“插件崩溃”);
}否则{
log('嘿,不需要黑客!!!');
}
}
var SomeView=Backbone.View.extend({
id:'div1',
render:function(){
这个.el.append(“你好,第三方,我是主干网”

”; 一些第三方插件(这个$el.attr('id'); 归还这个; } }); var SomeView2=Backbone.View.extend({ id:'div2', render:function(){ 这个.el.append(“你好,第三方,我是主干网”

”; 一些第三方插件(这个$el.attr('id'); 归还这个; } }); var myView1=newsomeview(); $('body').append(myView1.render().el); var myView2=newsomeview2(); $('body').append(myView2.el); myView2.render();
如果您不想使用
设置超时
黑客,我认为这种方式更“正常”:


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

应该这样做:

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

木偶示例,但idea也适用于主干视图

@whatbird:This
setTimeout(…,0)
技巧只设置了一个函数,当JavaScript全部完成并且控件返回到浏览器时调用该函数。因此,您的代码将设置所有内容并将所有内容添加到DOM中,然后浏览器接管并触发延迟函数。这是一个技巧,但很有用。如果在运行render之前将view.el插入DOM,则不需要使用此技巧。我不喜欢使用setTimeout hack,遵循一个好的流,它是永远不需要的。检查我的答案,解释在插入前运行render.el和在插入后运行render.el的区别。一个运行崩溃,另一个正常工作,没有setTimeout攻击@DanielAranda:但这会迫使调用者了解视图的实现细节,并对视图执行非标准操作。因此,这是一个你想要哪种类型的乱七八糟(或者在当地情况下哪种可能)的问题。@muistooshort我同意你的观点,我知道在渲染之前插入视图的元素不是强制性的;我总是尽量避免使用setTimeout,在这种情况下,我知道问题与DOM注入有关,我分享了一个如何在不使用setTimeout黑客的情况下修复它的示例。这对我来说很有效,但让我觉得不干净。也许是主干。混合使用渲染覆盖将更好地集中在一个地方。
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();
render: function() {
  Marionette.ItemView.prototype.render.apply(this, arguments);
  your code ...
}