2012-03-29 49 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秒編譯。

相關問題