Ember:通过childViews迭代

时间:2013-01-02 15:58:34

标签: coffeescript ember.js

我需要遍历一组子视图(这是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问题。如何确保循环完全执行?

1 个答案:

答案 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在循环播放时被修改。

有两种常见的解决方案:

  1. 向后迭代,以便更改不会影响即将发生的任何事情,它们只影响您已经完成的事情。
  2. 复制你正在迭代的内容,这样你就可以迭代一件事并改变别的东西。
  3. 第一个看起来像这样:

    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