[英]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
回調來觸發下一個超時,這可確保所有操作的順序與在簡單for
或each
循環中的順序相同。
我們的教訓是,如果你想使用那種進度指示器,你必須在混合中加入一些老式的偽合作多任務黑客。
將控制權交還給瀏覽器也會讓您在不期望的情況下對用戶交互開放。 您可能希望添加一個通用的UI阻止程序,以防止人們在您工作時點擊這些內容。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.