2017-02-23 77 views
0

背景: 我目前正在使用Knockout的UI。我一直在使用淘汰赛,但这个问题困扰了我。我正在尝试对一个名为Actions的可观察数组进行排序,并将其绑定到我创建的模板中的foreach。我通过创建一个正在调用Actions数组的排序函数的计算器进行绑定。Knockout Observable Array意外的排序

代码:

self.Actions = ko.observableArray([]); 

self.SortedActions = ko.computed(function() { 
return self.Actions() 
    .sort(function (a, b) { 
     var aOrder = Number(a.Order()); 
     var bOrder = Number(b.Order()); 

     return aOrder < bOrder ? 1 : -1; 
    }); 
}); 

<div class="row" data-bind="template: { name: 'action-template', foreach: SortedActions }"></div> 

预期结果: 我试图获取数组排序断顺序从1-n的每个动作的内部观察的。我已经知道,没有重复的命令,这不是一个问题,我知道所有的事情都是从1开始到n结束的整数。

实际结果: 当动作为<时,一切似乎都有效。但是,一旦它大于10,订单就不会像我期望的那样出现。每次我加载时它们都以相同的顺序出现,但是顺序不正确,看似随机。 (这意味着它看起来不像是一个明显的模式排序。例如按字母顺序排列)

如果有人有任何想法,为什么这不起作用,我将非常感激。我从来没有见过这种奇怪的行为,并完全陷入困境。请让我知道你是否需要更多的细节。这是我的第一篇文章,所以我可能会搞砸了。

谢谢, :)

+4

几件事情:'原始阵列上sort'行为,并且因此也将导致'self.Actions'进行排序。你应该使用'return bOrder - aOrder;'来获得正确的结果。 –

+0

你想实现一个总是处于排序状态的数组吗? – 4imble

+0

是的,我想要一个总是被排序显示的数组。这样当我重新排列动作时,我需要做的就是更改订单号。 –

回答

0

你可以使用一个订阅初始数组进行排序时,可观察到的变化,像这样。

请注意,这会对每一次更改进行排序,因此,如果您将一堆负载直接添加到observable中,将会非常浪费。你应该添加到底层数组,然后调用valueHasMutated()

如果你最终这样做,尽管你可能会在需要时调用数组的排序,这会更清晰。

var viewModel = function(){ 
 
    var self = this; 
 
    self.Actions = ko.observableArray(["one", "two", "three"]); 
 

 
    self.Actions.subscribe(function() { 
 
    console.log("sorting ..."); 
 
    self.Actions().sort(); 
 
    }); 
 
    
 
    // trigger sorting 
 
    self.Actions.push("zero"); 
 
    
 
    self.addnew = function(){ 
 
    self.Actions.push("new" + self.Actions().length); 
 
    } 
 
} 
 

 
ko.applyBindings(new viewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 

 
<ol data-bind="foreach: Actions"> 
 
    <li data-bind="text: $data"></li> 
 
</ol> 
 

 
<button data-bind="click: addnew">Add new</button>