在击倒JS排序可观测阵(Sorting Observable Array in Knockouts

2019-10-21 06:52发布

好了......所以我使用Twitter的引导。 我有可观察到的阵列,其表示一组基团。 在UI中,正在使用此observableArray呈现为每个组“标签”和“标签窗格”。 我可以排序,并通过他们的name属性显示这些群体,没有probs,抄吧!

<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>

这是伟大的......但是,我在这就需要将在组选项卡的开头显示的是同一阵列的“所有”对象。

目前标签看起来像这样... A | 所有| C | ç| d

需要看起来像这样...所有| A | C | ç| d

有任何想法吗? : - /

Answer 1:

调整你的排序功能。 在面向对象的方式,“所有”对象有指示它应该在顶部下令财产。 另外,在快速和肮脏的路要走是调整你的排序功能是这样的:

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上可观察到的(而无需调用它作为一个函数来获取观测到的值), 在观察到的内容进行排序。

下面是什么样子:

 function ViewModel(items) { var self = this; self.myArray = (items); self.myArray.sort(function (l, r) { if (l.name() === "All") return -1; if (r.name() === "All") return 1; return l.name().localeCompare(r.name()); }); }; var vm = new ViewModel([ { name: ko.observable("B") }, { name: ko.observable("A") }, { name: ko.observable("All") } ]); ko.applyBindings(vm); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> <ul data-bind="foreach: myArray" class="nav nav-tabs" role="tablist"> <li data-bind="text: name"></li> </ul> 

还是这个样子,如果你使用面向对象方法:

 function ViewModel(items) { var self = this; self.myArray = (items); self.myArray.sort(function (l, r) { if (!!l.isSpecialOption) return -1; if (!!r.isSpecialOption) return 1; return l.name().localeCompare(r.name()); }); }; var vm = new ViewModel([ { name: ko.observable("B") }, { name: ko.observable("A") }, { name: ko.observable("All"), isSpecialOption: true } ]); ko.applyBindings(vm); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> <ul data-bind="foreach: myArray" class="nav nav-tabs" role="tablist"> <li data-bind="text: name"></li> </ul> 



Answer 2:

我会处理这一切在视图模型,而不是在模板中做这件事。 理想的解决方案是,你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比在模板内联。

而相比于吉荣的答案,我认为这是非常清晰地处理特殊突部然后进行排序的休息,而不是试图把逻辑处理的特殊标签到您的排序算法FFT。



文章来源: Sorting Observable Array in Knockouts JS