If I have a collection with a comparator. ( in coffeescript )
class Words extends Backbone.collection
comparator: (word)->
word.get('score')
how do I keep the collection sorted if I am changing the score of the underlying items. The idea is to attach this to a list view where items with the lowest score are always at the top.
I've been manually calling sort on the collection every time I mutate an instance but this doesn't seem too efficient given that the whole list is sorted with one item.
I might perhaps try removing the mutated item and then add it again.
Any suggestions?
It looks like the rendering code is highly inefficient for one simple reason: DOM manipulation is expensive. Whenever possible, you should manipulate the DOM once rather than several times. All other optimization in JavaScript/CoffeeScript is secondary.
Here's the salient code (from the gist linked to from the second comment on ambertch's response):
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()
So, on render
, first the list's HTML is cleared; then for each word the list's HTML is cleared and the control is refreshed!
I'm not familiar with jQuery Mobile, so I'm not sure whether the main penalty is incurred on append
(as it is in jQuery) or on listview('refresh')
, but it's easy to rewrite the loop to avoid both, and remove some function defining/calling overhead as well:
render: ->
html = []
@model.each (word) ->
html.push(new WordView(model: word).render().el)
@list.empty().append(html)
Now you've got just one html
setter and one refresh
call, rather than one html
setter, n append
calls, and n+1 refresh
calls!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With