2011-04-02 7 views
7

Si tengo una colección con un comparador. (En CoffeeScript)colección de la columna vertebral manteniendo el orden de clasificación en la mutación modelo

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

¿Cómo puedo mantener la colección ordenada si estoy cambiando la puntuación de los elementos subyacentes. La idea es adjuntar esto a una vista de lista donde los elementos con el puntaje más bajo siempre están en la parte superior.

He estado llamando manualmente especie en la colección cada vez que una instancia mutar, pero esto no parece demasiado eficiente, dado que toda la lista está ordenada con un artículo.

Tal vez podría tratar de eliminar el elemento mutado y y luego agregarlo de nuevo.

¿Alguna sugerencia?

+3

+1 para usar CoffeeScript - ¡el _future_! –

Respuesta

5

Parece que el código de renderizado es muy ineficiente por una simple razón: La manipulación de DOM es costosa. Siempre que sea posible, debe manipular el DOM una vez en lugar de varias veces. El resto de la optimización en JavaScript/CoffeeScript es secundaria.

Aquí está el código saliente (de lo esencial vinculado a partir del segundo comentario sobre la respuesta de 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() 

Así, en render, primero HTML de la lista se borra; luego para cada palabra el código HTML de la lista se borra y ¡el control se actualiza!

No estoy familiarizado con jQuery Mobile, así que no estoy seguro de si la pena principal se incurre en append (como lo es en jQuery) o en listview('refresh'), pero es fácil volver a escribir el bucle para evitar ambas cosas, y eliminar algunas función que define/llamando sobrecarga así:

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

Ahora usted tiene sólo una html colocador y uno refresh llamada, en lugar de uno html organismo, nappend llamadas, y n + 1refresh llamadas!

+0

Voy a probar eso. Se ve prometedor. gracias – bradgonesurfing

+0

No funciona del todo. html = '' es una cadena mientras que html + = agrega objetos DOM. Tratando de arreglarlo .... – bradgonesurfing

+0

resulta que el bit realmente lento es la llamada @refresh donde jquery mobile ui vuelve a renderizar el chrome para la interfaz de usuario. Tenía un código realmente malo que viste donde llamé para refrescar varias veces. Eliminar eso fue una gran ayuda. – bradgonesurfing

0

¿Qué tal unir todos los modelos iniciales de Words para ordenar en un evento de cambio y luego enlazar el mismo en un evento add a la colección?

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

Backbone.Collection.sort desencadena una actualización, por lo que a continuación, sólo: "toda la lista está ordenada con un elemento"

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

En cuanto a su preocupación por la eficiencia, lo que quiere usted decir con A menos que tenga miles de elementos (e incluso entonces, ejecute algunos puntos de referencia en varios navegadores, apuesto a que todavía sería bastante rápido), no debería hacer mucha diferencia con los navegadores/computadoras modernos

Si realmente estuviera preocupado al respecto, supongo que puede hacer algunas de las técnicas de optimización para mantener los conjuntos más grandes ordenados. Por ejemplo, colóquelos en grupos de puntuación (0-100, 100-500, 500-1000, etc.), luego coloque la puntuación en el depósito y solo ordene dentro del depósito (el algoritmo de clasificación real es por implementación de navegador, Backbone - o Subraye más bien, solo lo llama). Puede google para algoritmos como este. Pero es mucho trabajo con poca ganancia frente al aumento en la complejidad del código.

De nuevo, sin embargo, necesitaría una gran cantidad de perfiles y evaluaciones comparativas para determinar si realmente vale la pena.

+0

resulta que no es la clasificación que es un asesino de rendimiento sino la re-representación de la lista en una plataforma móvil. Solo tengo unos 40 elementos y mi lista vuelve a aparecer en 3 segundos. Estoy usando la interfaz de usuario móvil de JQuery en HTC desire. – bradgonesurfing

+0

La esencia del código de renderizado está en https://gist.github.com/899825 perhapps Estoy haciendo algo estúpido en el código de renderizado ?? – bradgonesurfing

Cuestiones relacionadas