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