【问题标题】:Ember: Iterating through childViewsEmber:遍历 childViews
【发布时间】:2012-12-16 23:57:45
【问题描述】:

我需要遍历一组子视图(它们是 UI 小部件)并告诉他们将自己从应用程序中删除。我已确保集合中存在所有子视图,但是此代码一次只会在几个子视图/小部件上调用 removeIfSelected():

 widgets = container.get('childViews')
 widget.removeIfSelected() for widget in widgets

例如,如果有 3 个小部件,则第一次运行时(通过删除按钮)会删除 2 个小部件。我必须再次单击该按钮才能删除最后一个小部件。

如果有 2 个,它将删除一个小部件。如果有 4 个或更多,除了 2 个小部件之外的所有小部件都被删除,我必须再单击 2 次删除才能删除最后两个。

我最初的解决方案是运行循环 3 次,以确保删除所有小部件,但这没有通过代码审查,我必须找到一个真正的解决方案。我不确定这是咖啡脚本问题还是 Ember.js 问题。如何确保循环完全执行?

【问题讨论】:

    标签: coffeescript ember.js


    【解决方案1】:

    听起来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)
    

    a 中留下[1, 2, 4, 5],因为a 在循环时正在被修改。

    对此有两种常见的解决方案:

    1. 向后迭代,以便更改不会影响即将发生的任何事情,而只会影响您已经经历过的事情。
    2. 复制您正在迭代的内容,以便您迭代一件事并更改其他内容。

    第一个看起来像这样:

    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
    

    【讨论】:

    • 不敢相信我忽略了这一点。克隆方法效果很好。谢谢。
    • 我觉得可以使用ember.js内置的函数toArray(), `container.get('childViews').toArray()) 作为克隆方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-08
    • 2023-03-16
    • 2014-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多