2012-03-29 54 views
0

我正在开发应用程序,使用backbone.js & jquery。我在模型下面的代码:Backbone.js&jquery - show()元素

runReport: function() { 
    this.set({generatingReport: true});  
    //long computation... 
    this.set({generatingReport: false});  
} 

,并按照相应的视图代码(初始化函数):

... 
var that = this; 
... 

this.model.bind("change:generatingReport", function() {      
    if(that.model.get("generatingReport") === true) { 
     $("#report").empty().append("<h1>Generating report...</h1>").show(0); 
     console.log("begin"); 
    } else if(that.model.get("generatingReport") === false) { 
     $("#report").empty().append("<h1>Report generated</h1>").show(0); 
     console.log("end"); 
    } 
}); 

这里是查看代码运行的动作:

... 
events { 
    "click #btn-run": "runReport" 
} 
... 
runReport: function() { 
    this.model.runReport(); 
} 

我的问题是根本没有显示“Generatin report ...”消息(打印日志消息)。生成报告时出现“生成报告”。

如果我下面(见IF分支添加警报):

this.model.bind("change:generatingReport", function() {      
    if(that.model.get("generatingReport") === true) { 
     $("#report").empty().append("<h1>Generating report...</h1>").show(0); 
     console.log("begin"); 
     alert("stop!"); 
    } else if(that.model.get("generatingReport") === false) { 
     $("#report").empty().append("<h1>Report generated</h1>").show(0); 
     console.log("end"); 
    } 
}); 

然后 “生成报表...” 显示。在“长计算...”部分,没有可能隐藏消息的隐藏jquery调用。

任何想法这里发生了什么?

+0

顺便说一句,长时间的计算需要大约20秒,所以“生成报告...”被立即替换为“生成报告”并非立即生效# – 2012-03-29 21:09:29

+0

“#报告”在哪里?它是视图控制的HTML的一部分,它的一部分是'el'?还是它已经存在的页面的另一部分? – 2012-03-29 21:13:01

+0

是的,它是视图控件的参数 – 2012-03-30 04:11:44

回答

1

我想这里可能发生的事情是,浏览器从来没有机会更新UI。您的长时间计算全部发生在点击事件的事件处理程序中。浏览器可能(我在这里说“可能”很多,因为我并不是真正的浏览器线程模型专家!)会将click事件分派给您的Javascript代码,然后等待您的事件处理程序完成,然后再更新/重绘UI 。在这种情况下,在长时间过程结束之前,您不会控制(完成),所以UI只在最后重新绘制一次。 DOM的#report节点会根据您的代码进行内部更改,但直到您的过程完成后,它才有机会在屏幕上自行重绘。我不知道这是否是最佳的,但这样的事情可能会有所帮助:

runReport: function() { 
    var self = this; 
    this.set({generatingReport: true}); 

    // By calling delay, runReport() will exit immediately so UI can redraw 
    _.delay(function() { 
    //long computation... 
    self.set({generatingReport: false}); 
    }, 50); 
} 

我只是用下划线的延迟()函数存在推迟长处理50毫秒。通过这样做,runReport()函数可以立即退出,启动整个事件链的单击事件处理程序可以完成执行,并且UI可以重绘本身以显示“生成报告...”消息。经过非常短的(50毫秒)延迟后,长计算将开始,并且完成后,generateReport将设置为false,UI将再次更新。

+0

嗨,这个简单的黑客帮助,现在这两个消息都呈现(一毫秒足够:)但是,正如你写的,我不认为这是最佳的解决方案。不管怎样,谢谢。 – 2012-03-30 04:49:08

+0

是的,它看起来有点不好,但我认为这基本上是你如何做到的。 Javascript(至少在浏览器中)只是单线程的,所以你不能真正做一个长时间运行的任务,并且同时处理用户输入。我已经看到其他人建议你编写长时间运行的任务(可能会进行某种循环),以便它们每隔一段时间就控制回UI线程: http://stackoverflow.com/questions/672732 /防止-长期运行的JavaScript从 - 锁定 - 上 - 浏览器 – heavi5ide 2012-04-02 22:50:18

0

这是因为DOM操作比您提到的@ heavi5ide的runReport函数慢。

如果您的报告生成几乎是即时的,则不需要任何“生成报告...”消息。你也可以这样做:

runReport: function() { 
    var self = this; 
    var timer = setTimeout(function() { 
     self.set({generatingReport: true}); 
    }, 500); 

    // 
    // report calculation code 
    // 

    if (this.get("generatingReport")) this.set({ generatingReport : false }); 

    clearTimeout(timer); 

} 

这样做,你将激活generatingReport消息仅在报表的时间超过0.5秒编译。

相关问题