2012-03-04 41 views
0

具有可觀察到的陣列,像這樣:步行多維JavaScript數組向前或向後

  this.list = ko.observableArray([ 
      new GoalItem(1, 'page', 'Getting started', 0, '', [ 
       new GoalItem(2, 'page', 'Getting started 1.1', 0, ''), 
       new GoalItem(3, 'video', 'Video', 0, '', [ 
        new GoalItem(4, 'data', 'Data', 0, ''), 
        new GoalItem(5, 'test', 'Test', 0, '', [ 
         new GoalItem(6, 'page', 'Test prep', 0, '', [ 
          new GoalItem(7, 'video', 'Test video', 0, ''), 
          new GoalItem(8, 'file', 'Test file', 0, '') 
         ]) 
        ]), 
        new GoalItem(9, 'page', 'Sample page', 0, '') 
       ]) 
      ]), 
      new GoalItem(10, 'page', 'More data tracking', 0, '', [ 
       new GoalItem(11, 'data', 'Data 1', 0, ''), 
       new GoalItem(12, 'data', 'Data 2', 0, '') 
      ]) 
     ]); 

,並假設當前活動的產品

new GoalItem(4, 'data', 'Data', 0, '') 

怎麼能/我會「走」

this.list 

得到「下一個」應該是

new GoalItem(5, 'test', 'Test', 0, '', [ 
         new GoalItem(6, 'page', 'Test prep', 0, '', [ 
          new GoalItem(7, 'video', 'Test video', 0, ''), 
          new GoalItem(8, 'file', 'Test file', 0, '') 
         ]) 
        ]), 

或獲得 「以前的」 項目應該是

new GoalItem(3, 'video', 'Video', 0, '', [ 
        new GoalItem(4, 'data', 'Data', 0, ''), 
        new GoalItem(5, 'test', 'Test', 0, '', [ 
         new GoalItem(6, 'page', 'Test prep', 0, '', [ 
          new GoalItem(7, 'video', 'Test video', 0, ''), 
          new GoalItem(8, 'file', 'Test file', 0, '') 
         ]) 
        ]), 
        new GoalItem(9, 'page', 'Sample page', 0, '') 
       ]) 
與功能

非常喜歡

this.list.next() 

this.list.previous() 

希望這是有道理的。

謝謝!

+0

您需要保留活動項目的索引,並在需要下一個(遞增索引)或prev(遞減索引)時使用它。 – veblock 2012-03-04 22:34:16

回答

2

有幾種方法可以處理這個問題。

我認爲一個簡單的方法來處理它是創建一個計算的觀察值,它表示一個扁平化的結構版本。這樣,隨着各種陣列的變化,它將始終是正確的。

下面是一個方法的樣本子項遞歸添加到計算觀察到的

//to be called recursively 
var addChildren = function(array, result) { 
    array = ko.utils.unwrapObservable(array); 
    if (array) { 
     for (var i = 0, j = array.length; i < j; i++) { 
      result.push(array[i]); 
      addChildren(array[i].children, result); 
     }   
    } 
}; 

//a flattened versions of the items 
this.flatItems = ko.computed(function() { 
    var result = []; 
    addChildren(self.items(), result); 
    return result; 
}); 

這裏是顯示了通過flatItems移動下一首/上一個樣本:http://jsfiddle.net/rniemeyer/VHEYK/

你可以這樣做只需要做更多的循環來找到每個項目的位置或附加元數據,所以你現在如何從一個項目返回到父項。

+0

另一個夢幻般的答案!易於實施和工作沒有問題。非常感激! – Andre 2012-03-05 03:17:54

+0

這可能會證明它自己的問題,如果是這樣,請事先道歉。我使用[link](http://mjsarfatti.com/sandbox/nestedSortable)在UI中呈現this.list - 一旦「drop」完成,顯然previous() - next()不在同步。有沒有一種解決方案可以基於新元素的佈局來觸發可觀察數組的重新排序? – Andre 2012-03-05 04:02:10

+1

我沒有特別注意你正在使用的插件,但我寫了一個綁定,可以與jQuery UI可排序功能一起使用。該項目位於:https://github.com/rniemeyer/knockout-sortable。綁定將確保observableArrays保持同步並具有一些回調以進一步自定義行爲。 http://jsfiddle.net/rniemeyer/VHEYK/1/ – 2012-03-05 14:10:10