将骨干视图与集合一起订购

Chr*_*gel 5 sorting collections view backbone.js

我有一个集合,其中包含几个应该可以在列表中访问的项目.

因此集合中的每个元素都会获得自己的视图元素,然后将其添加到DOM中的一个容器中.

我的问题是:如何使用比较器函数将我在集合中实现的排序顺序应用于DOM?第一次渲染很简单:迭代集合并创建所有视图,然后以正确的顺序将其附加到容器元素.

但是,如果模型被更改并被集合重新排序,该怎么办?如果添加了元素怎么办?我不想重新渲染所有元素,而是只更新/移动必要的DOM节点.

Vin*_*lia 7

模特补充

添加元素的路径非常简单,因为index当模型添加到集合时,您可以获得选项.此索引是排序索引,如果您有一个简单的视图,则应该很容易将视图插入某个索引.

排序属性更改

这个有点棘手,而且我没有一个方便的答案(我有时也会遇到这个问题),因为在更改模型排序的属性后,集合不会自动重新调整其顺序你最初添加它.

来自骨干文档:

如果稍后更改模型属性,具有比较器功能的集合将不会自动重新排序,因此您可能希望在更改可能影响订单的模型属性后调用sort.

因此,如果您对集合调用sort,它将触发一个reset事件,您可以将其挂钩以触发重绘整个列表.

在处理相当长的列表并且可能严重降低用户体验甚至导致挂起时,它非常无效

所以你从这里得到的一些东西就是知道你可以:

  • 总是在通过调用排序后找到模型的索引 collection.indexOf(model)
  • add事件中获取模型的索引(第三个参数)

编辑:

在思考了一下之后我想出了类似的东西:

var Model = Backbone.Model.extend({
    initialize: function () {
        this.bind('change:name', this.onChangeName, this);
    },
    onChangeName: function ()
    {
        var index, newIndex;

        index = this.collection.indexOf(this);
        this.collection.sort({silent: true});
        newIndex = this.collection.indexOf(this);
        if (index !== newIndex)
        {
            this.trigger('reindex', newIndex);
            // or
            // this.collection.trigger('reindex', this, newIndex);

        }
    }
});
Run Code Online (Sandbox Code Playgroud)

然后在你看来你可以听

var View = Backbone.View.extend({
    initialize: function () {
        this.model.bind('reindex', this.onReindex, this);
    },
    onReindex: function (newIndex)
    {
        // execute some code that puts the view in the right place ilke
        $("ul li").eq(newIndex).after(this.$el);
    }
});
Run Code Online (Sandbox Code Playgroud)