2013-01-02 39 views
0

我需要遍歷子視圖集合(其中是UI小工具),並告訴他們從應用程序中刪除自己。我要確保所有的childViews存在集合中,但是這個代碼將只在少數的childViews /部件的同時調用removeIfSelected():Ember:迭代通過子視圖

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

例如,如果有3個窗口小部件,第一次運行(通過刪除按鈕)2個小部件被刪除。我必須再次單擊該按鈕才能刪除最後一個小部件。

如果有2個,它將刪除一個小部件。如果有4個或更多,除了2個小部件都將被刪除,而我必須再次單擊刪除2次以刪除最後兩個小部件。

我最初的解決方案是運行循環3次,以保證所有小部件都被刪除,但是這並沒有通過代碼審查,我不得不尋找一個真正的解決方案。我不確定這是咖啡問題還是Ember.js問題。我如何確保循環完全執行?

回答

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) 

讓你在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 
+0

不能相信我忽略了這個。克隆方法非常完美。謝謝。 – unmuse

+0

我想你可以使用內置的ember.js函數toArray(),'container.get('childViews')。toArray())作爲克隆方法。 –