Javascript 敲除JS中可观测数组的排序

Javascript 敲除JS中可观测数组的排序,javascript,twitter-bootstrap,knockout.js,Javascript,Twitter Bootstrap,Knockout.js,好的。。。所以我用的是推特引导。我有一个可观察的数组,它代表一组组。在UI中,此observableArray用于为每个组呈现“选项卡”和“选项卡窗格”。我可以按名称属性对这些组进行排序和显示,没问题,没错 <ul data-bind="foreach: myArray().sort(function (l, r) { return l.name() > r.name() ? 1 : -1 })" class="nav nav-tabs" role="tablist">

好的。。。所以我用的是推特引导。我有一个可观察的数组,它代表一组组。在UI中,此observableArray用于为每个组呈现“选项卡”和“选项卡窗格”。我可以按名称属性对这些组进行排序和显示,没问题,没错

<ul data-bind="foreach: myArray().sort(function (l, r) { return l.name() > r.name() ? 1 : -1 })" class="nav nav-tabs" role="tablist">
    <li data-bind="text: name"></li>
</ul>
太好了。。。但是,我在同一数组中有一个“All”对象,它需要位于显示的选项卡集的开头

选项卡当前看起来像这样。。。A | All | B | C | D

需要看起来像这样。。。全部| A | B | C | D


有什么想法吗?:-/

调整排序函数。在面向对象的方式中,“All”对象将具有一个属性,指示它应该在顶部排序。或者,快速而肮脏的方法是将排序函数调整为如下所示:

function (l, r) {
    if (l.name === "All") return 1;
    if (r.name === "All") return -1;
    return l.name().localeCompare(r.name());
}
我想我的+1/-1逻辑是正确的,但是你有单元测试来解决这些细节,对吗?;)

作为补充说明,我将使用
localeCompare
函数来比较字符串


附议@MattBurland的评论,您也应该将排序逻辑移到视图模型中(无论如何,单元测试都需要这样做)。此外,请注意,
sort
将对数组本身进行排序,您还可以对可观察对象调用
sort
(无需将其作为获取可观察对象值的函数调用),以对可观察对象的内容进行排序

下面是它的样子:

功能视图模型(项目){
var self=这个;
self.myArray=(项);
self.myArray.sort(函数(l,r){
if(l.name()=“All”)返回-1;
如果(r.name()=“All”)返回1;
返回l.name().localeCompare(r.name());
});
};
var vm=新的视图模型([
{name:ko.observable(“B”)},
{name:ko.observable(“A”)},
{name:ko.observable(“All”)}
]);
ko.应用绑定(vm)


我会在ViewModel中处理所有这些,而不是在模板中处理。理想的解决方案是,您的allTab已经与其他选项卡分开,但如果不是这样,您可能需要遍历其他选项卡并找到它

vm.sortedTabs = ko.computed(function () {
    var allTab = ?;
    var otherTabs = ?; //I don't know enough about your VM to know where you get these

    return [allTab].concat(otherTabs.sort(sortFunction)); 
});
那么你的模板就是

<ul data-bind="foreach: sortedTabs" class="nav nav-tabs" role="tablist">
    <li data-bind="text: name"></li>
</ul>
但是这种排序逻辑在VM中比在模板中内联处理容易得多


与Jeroen的答案相比,我认为处理一个或多个特殊选项卡然后对其余选项卡进行排序要清晰得多,而不是试图将处理特殊选项卡的逻辑放入排序算法中。

A
位于
所有
之前,因此您的排序是正确的。如果希望它以不同的方式排序,则必须添加一个子句来处理
All
。但是,将模型逻辑从您的视图中移除,并将其放在
computed
属性中,这样会更干净。感谢您的反馈。我知道“A”在“All”之前,哈哈。只是不确定我如何在视图中添加附加条件,但您已经回答了我的问题,我想。。。我将尝试输入一个计算属性。感谢您的反馈,我会回复您;-)