2017-02-23 78 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>