0

子ビュー (UI ウィジェット) のコレクションを反復処理し、アプリから自分自身を削除するように指示する必要があります。すべての childViews がコレクションに存在することを確認しましたが、このコードは一度にいくつかの childViews/widgets でのみ removeIfSelected() を呼び出します:

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

たとえば、3 つのウィジェットがある場合、これが初めて実行されると (削除ボタンを使用)、2 つのウィジェットが削除されます。最後のウィジェットを削除するには、もう一度ボタンをクリックする必要があります。

2 つある場合は、1 つのウィジェットが削除されます。4 つ以上ある場合は、2 つを除くすべてのウィジェットが削除され、最後の 2 つを削除するには、さらに 2 回削除をクリックする必要があります。

私の最初の解決策は、すべてのウィジェットが削除されることを保証するループを 3 回実行することでしたが、これはコード レビューに合格しなかったため、実際の解決策を見つける必要がありました。これが coffeescript の問題なのか、Ember.js の問題なのかはわかりません。ループが完全に実行されるようにするにはどうすればよいですか?

4

1 に答える 1

2

背後で配列widget.removeIfSelected()を変更しているように聞こえるので、何かを削除するとすぐに、ループ内の長さとインデックスがすべて台無しになります。このループを考えてみましょう:widgetsfor

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]あなたを残します。aa

これには、次の 2 つの一般的な解決策があります。

  1. 変更が今後発生するものには影響を与えず、すでに経験したことだけに影響を与えるように、逆方向に繰り返します。
  2. 繰り返しているもののコピーを作成して、1 つのことを繰り返し、別のものを変更するようにします。

最初は次のようになります。

for i in [widgets.length - 1 .. 0] by -1
    widget.removeIfSelected()

2番目は次のようになります。

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
于 2013-01-02T18:45:21.987 に答える