7

如果我有一个带有比较器的集合。(在咖啡脚本中)

class Words extends Backbone.collection
    comparator: (word)->
        word.get('score')

如果要更改基础项目的分数,如何保持集合排序。这个想法是将其附加到列表视图中,其中得分最低的项目始终位于顶部。

每次我对一个实例进行变异时,我都会在集合上手动调用 sort ,但考虑到整个列表是用一个项目排序的,这似乎不太有效。

我可能会尝试删除变异的项目,然后再次添加。

有什么建议么?

4

2 回答 2

5

看起来渲染代码效率很低,原因很简单:DOM 操作成本很高。只要有可能,您应该操作 DOM 一次而不是多次。JavaScript/CoffeeScript 中的所有其他优化都是次要的。

这是显着的代码(来自与 ambertch 回复的第二条评论相关的要点):

refresh: ->
    @list.listview("refresh")

appendWord: (word)->
    wv = new WordView({model: word}).render().el
    @list.append( wv )
    @refresh()

render: ->
    @list.html("")
    @model.each (word) => @appendWord(word)
    @refresh()

因此,在 上render,首先清除列表的 HTML;然后对于每个单词,列表的 HTML 都会被清除刷新控件!

我对 jQuery Mobile 不熟悉,所以我不确定主要惩罚是在append(因为它在 jQuery 中)还是在 上listview('refresh'),但很容易重写循环以避免两者,并删除一些函数定义/调用开销以及:

render: ->
  html = []
  @model.each (word) ->
    html.push(new WordView(model: word).render().el)
  @list.empty().append(html)

现在你只有一个htmlsetter 和一个refreshcall,而不是一个htmlsetter、n 个 appendcall 和n+1 个 refreshcall!

于 2011-04-03T04:38:14.253 回答
0

如何绑定所有单词的初始模型以对更改事件进行排序,然后在添加事件上将其绑定到集合?

_(self).models.each(model) { model.bind('change', self.sort) } // bind on the model add as well

Backbone.Collection.sort 触发刷新,因此只需:

this.bind('refresh', this.refresh)

至于您对效率的关注,您所说的“整个列表按一项排序”是什么意思?除非你有成千上万的项目(即使那样,在各种浏览器中运行一些基准测试,我敢打赌它仍然会非常快),它与现代浏览器/计算机应该没有太大区别

如果你真的很关心它,我想你可以做一些优化技术来保持更大的集合排序。例如,将它们放入分数桶中(0-100、100-500、500-1000 等),然后将分数放入桶中并仅在桶内排序(实际排序算法是每个浏览器实现的,Backbone -或下划线,只是调用它)。你可以谷歌搜索这样的算法。但与代码复杂性的增加相比,这是一项收效甚微的工作。

不过,同样,您需要进行大量分析和基准测试来确定这是否真的值得。

于 2011-04-02T18:49:19.307 回答