我需要遍历一组子视图(这是UI Widgets),并告诉他们从应用程序中删除自己。我确保所有的childView都存在于集合中,但是这段代码一次只能调用一些childViews / widgets上的removeIfSelected():
widgets = container.get('childViews')
widget.removeIfSelected() for widget in widgets
例如,如果有3个小部件,则第一次运行此小部件(通过删除按钮)将删除2个小部件。我必须再次单击该按钮才能删除最后一个小部件。
如果有2则会删除一个小部件。如果有4个或更多,则除去2个小部件,我必须再次单击删除2次以删除最后两个。
我的初始解决方案是运行循环3次,这保证所有小部件都被删除,但是这没有通过代码审查,我必须找到一个真正的解决方案。我不确定这是一个coffeescript问题还是一个Ember.js问题。如何确保循环完全执行?
答案 0 :(得分:2)
widget.removeIfSelected()
之类的声音正在改变背后的widgets
数组,因此只要删除了某些内容,for
循环中的长度和索引就会全部搞砸。考虑这个循环:
a = [ 0, 1, 2, 3, 4, 5 ]
for e, i in a
console.log(i) if(i % 2 == 0)
这显然会在控制台中产生0, 2, 4
。但是,这个:
a = [ 0, 1, 2, 3, 4, 5 ]
for e, i in a
a.splice(i, 1) if(i % 2 == 0)
console.log(a)
在[1, 2, 4, 5]
中留下a
因为a
在循环播放时被修改。
有两种常见的解决方案:
第一个看起来像这样:
for i in [widgets.length - 1 .. 0] by -1
widget.removeIfSelected()
第二个看起来像这样:
widgets = clone(container.get('childViews'))
widget.removeIfSelected() for widget in widgets
clone
是你可以制作(浅)数组副本的地方。如果您有下划线,那么您可以使用_.clone
:
widgets = _(container.get('childViews')).clone()
你也可以手工完成:
clone = (a) -> e for e in a