Knockout observableArray排序没有在UI中反映(foreach绑定)

时间:2015-07-14 16:36:35

标签: javascript html sorting knockout.js

我将数据从网格添加到标记列表中(通过检查数据行)。当发生这种情况时,我希望对标签列表进行排序(例如按名称按字母顺序排序)。

排序结果显然必须反映在用户界面中,但是从我尝试的内容中反映出来并不符合我的情况。

以下是小提琴示例:http://jsfiddle.net/hLpLobo2/5/

为了确保排序,请在sortPersonsAlphabetically foreach回调中调用afterAdd函数:

<div class="tag-list" data-bind="foreach: { 
                                data: tags, as: 'tag',
                                afterAdd: sortPersonsAlphabetically
}">
    <div class="tag-item">
        <span class="tag-item-value tag-item-value-name" data-bind="text: tag.name"></span>
        <span class="tag-item-separator">:</span>
        <span class="tag-item-value tag-item-value-age" data-bind="text: tag.age"></span>
    </div>
</div>

但奇怪的是,只有在添加另一个项目后才能工作(&#34;第二个选择&#34;)。

在我提供的小提琴示例中,我还添加了一个<pre>标记,其中很清楚数组已正确排序,但它没有反映在标记列表UI中。< / p>

我还尝试将排序功能包裹在setTimeout 1ms的延迟中,这似乎可以解决它,但是有一些可见的闪烁,在我看来,这是不可接受的,并且它是&#39;更多的是黑客攻击。

有干净的方法吗?

1 个答案:

答案 0 :(得分:4)

Afteradd的目的是更新DOM以响应数据的变化,而不是对数据进行进一步的更改。你得到的结果很奇怪,但我同意。

我建议您使用计算机生成已排序的标签

self.sortedTags = ko.computed(function () {
    var data = self.tags();
    return data.sort(function(left, right) {
        return left.name == right.name ? 0 : (left.name < right.name ? -1 : 1);
    });
});

并在你的foreach中显示:

<div class="tag-list" data-bind="foreach: { 
                                data: sortedTags, as: 'tag'
}">

http://jsfiddle.net/hLpLobo2/6/

相关问题