[英]Update DOM while iterating over Backbone Collection?
So I am trying to display a loading bar when rendering very large collections. 因此,我在渲染非常大的集合时尝试显示加载栏。 I have a placeholder for the loading bar when the page initially loads, and I am trying to update it like this:
当页面最初加载时,我有一个占位符用于加载栏,我试图像这样更新它:
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
The problem here is that the DOM isnt updated until the addAll
function completes. 这里的问题是DOM没有更新,直到
addAll
函数完成。 I have a feeling that this is me not understanding some basic JS fundamentals. 我有一种感觉,这是我不理解一些基本的JS基础知识。 Any help would be greatly appreciated!
任何帮助将不胜感激!
Yes, you are missing something fundamental: the browser won't do any of its own work until your code returns control to the browser. 是的,你缺少一些基本的东西:在你的代码将控制权返回给浏览器之前,浏览器不会做任何自己的工作。
Consider some code like this: 考虑一下这样的代码:
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')
You'll see a brief pause and then #bar
and #n
will be updated and done
will appear in the console. 您将看到一个短暂的暂停,然后
#bar
和#n
将更新并done
将显示在控制台中。 Demo: http://jsfiddle.net/ambiguous/f5qKV/ (you might need to increase the 1000 to make things more obvious). 演示: http : //jsfiddle.net/ambiguous/f5qKV/ (您可能需要增加1000以使事情变得更加明显)。
However, if you return control to the browser with setTimeout(..., 0)
on each iteration: 但是,如果在每次迭代时使用
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)
you'll be able to see #bar
and #n
changing and then you'll see done
in the console when everything has finished. 你就可以看到
#bar
和#n
变化,然后你就会看到done
在控制台时,一切都已经结束了。 Demo: http://jsfiddle.net/ambiguous/UCbY8/1/ 演示: http : //jsfiddle.net/ambiguous/UCbY8/1/
Note that the setTimeout
version uses the setTimeout
callback to trigger the next timeout, that ensures that everything happens in the same order as they would in a simple for
or each
loop. 请注意,
setTimeout
版本使用setTimeout
回调来触发下一个超时,这可确保所有操作的顺序与在简单for
或each
循环中的顺序相同。
The lesson is that you have to add some old-school pseudo cooperative multi-tasking hacks into the mix if you want to use that kind of progress indicator. 我们的教训是,如果你想使用那种进度指示器,你必须在混合中加入一些老式的伪合作多任务黑客。
Handing control back to the browser also leaves you open to user interaction when you're not expecting it. 将控制权交还给浏览器也会让您在不期望的情况下对用户交互开放。 You might want to add a general UI blocker to keep people from clicking on things while you're working if you go this route.
您可能希望添加一个通用的UI阻止程序,以防止人们在您工作时点击这些内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.