簡體   English   中英

在Backbone Collection上迭代時更新DOM?

[英]Update DOM while iterating over Backbone Collection?

因此,我在渲染非常大的集合時嘗試顯示加載欄。 當頁面最初加載時,我有一個占位符用於加載欄,我試圖像這樣更新它:

addAll: 
  @collection.each(((obj, index) ->
    @addOne(obj, index)), this
  )

addOne: (obj, index) ->
  percent_complete = ((index / @collection.length) * 100)
  $(".loading_bar").width("#{percent_complete}%")
  # Proceed with rendering, create the view, etc

這里的問題是DOM沒有更新,直到addAll函數完成。 我有一種感覺,這是我不理解一些基本的JS基礎知識。 任何幫助將不勝感激!

是的,你缺少一些基本的東西:在你的代碼將控制權返回給瀏覽器之前,瀏覽器不會做任何自己的工作。

考慮一下這樣的代碼:

collection = [1..1000]

addOne = (index) ->
  $('#n').text(index + 1)
  percent_complete = ((index + 1) / collection.length) * 100
  $("#bar").width("#{percent_complete}%")

addOne(i) for e,i in collection  
console.log('done')

您將看到一個短暫的暫停,然后#bar#n將更新並done將顯示在控制台中。 演示: http//jsfiddle.net/ambiguous/f5qKV/ (您可能需要增加1000以使事情變得更加明顯)。

但是,如果在每次迭代時使用setTimeout(..., 0)將控制權返回給瀏覽器:

collection = [1..1000]

addOne = (index) ->
  $('#n').text(index + 1)
  percent_complete = ((index + 1) / collection.length) * 100
  $("#bar").width("#{percent_complete}%")

i = 0
timeOut = ->
    if(i == collection.length)
        console.log('done')
        return
    addOne(i++)
    setTimeout(timeOut, 0)
setTimeout(timeOut, 0)

你就可以看到#bar#n變化,然后你就會看到done在控制台時,一切都已經結束了。 演示: http//jsfiddle.net/ambiguous/UCbY8/1/

請注意, setTimeout版本使用setTimeout回調來觸發下一個超時,這可確保所有操作的順序與在簡單foreach循環中的順序相同。

我們的教訓是,如果你想使用那種進度指示器,你必須在混合中加入一些老式的偽合作多任務黑客。


將控制權交還給瀏覽器也會讓您在不期望的情況下對用戶交互開放。 您可能希望添加一個通用的UI阻止程序,以防止人們在您工作時點擊這些內容。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM