2012-02-24 19 views
19

Me estoy quedando un poco atascado implementado un comparador de red troncal, básicamente quiero seleccionar diferentes métodos de clasificación basados ​​en la ruta y usar el comparador para ordenar la colección. Idealmente, quiero mantener la lógica de clasificación encapsulada dentro de la colección, pero parece que se está estancando. Por ejemploimplementar correctamente los comparadores de la red troncal

Requests = Backbone.Collection.extend({ 
     model : Request, 
     comparator : function(ab) { 
      return -ab.id; 
     },   
     nooffers : function() { 
      return this.sortBy(function(ab) {    
       return ab.get('offers'); 
      }); 
     } 
    }); 

lo que por defecto ordena basa en el comparador por defecto - pero en mi enrutamiento deseo de poder recurrir, por ejemplo, hacer algo como

routes : { 
     "" : "index", 
     '/ordering/:order' : 'ordering' 
    }, 
    ordering : function(theorder) { 
     ordering = theorder; 
     if(theorder == 'nooffers') { 
      Request.comparator = Request.nooffers(); 
     } 
     Request.sort(); 
     listView.render(); 
     howitworksView.render(); 
    } 

Sin embargo, en ese caso, me sale un error ('c.call no es una función') alguna idea?

+1

La respuesta fue buena, pero la pregunta también merecía algo de amor (para obtener la respuesta) :-) – jmk2142

Respuesta

47

Tiene algunas cosas mal aquí.

Esto no hace lo que usted cree:

if(theorder == 'nooffers') { 
    Request.comparator = Request.nooffers(); 
} 

que ejecuta el método nooffers y asigna el resultado a Request.comparator. Pero sortBy devuelve la lista ordenada:

nooffers : function() { 
    return this.sortBy(function(ab) {    
     return ab.get('offers'); 
    }); 
} 

y el establecimiento de esa lista como la función de comparación no hace nada útil.

desea cambiar la asignación de utilizar la función en lugar de que su valor de retorno:

if(theorder == 'nooffers') { 
    Request.comparator = Request.nooffers; 
} 

y cambiar la función de ser una función de comparación válida:

nooffers : function(ab) { 
    return ab.get('offers'); 
} 

Demo (correr con su consola abierta): http://jsfiddle.net/ambiguous/AAZCa/

Pero tener a alguien del exterior jugueteando con los métodos de la colección como ese huele mal y no deberías hazlo. En su lugar, usted debe preguntar a la colección de cambiar su ordenación con algo como esto:

var Requests = Backbone.Collection.extend({ 
    model: Request, 
    comparator: function(ab) { 
     if(this._order_by == 'offers') 
      return ab.get('offers'); 
     else if(this._order_by == 'id') 
      return -ab.id; 
     //... 
    }, 
    order_by_offers: function() { 
     this._order_by = 'offers'; 
     this.sort(); 
    }, 
    order_by_default: function() { 
     this._order_by = 'id'; 
     this.sort(); 
    }, 
    _order_by: 'id' 
}); 
//... 
rs.order_by_offers(); 

Demostración: http://jsfiddle.net/ambiguous/uM9av/

O puede dejar que el canje de recogida su propio comparator para evitar toda la lógica condicional dentro de la comparator:

var Requests = Backbone.Collection.extend({ 
    model: Request, 
    initialize: function() { 
     this._order_by_id = this.comparator; 
    }, 
    comparator: function(ab) { 
     return -ab.id; 
    }, 
    order_by_offers: function() { 
     this.comparator = this._order_by_offers; 
     this.sort(); 
    }, 
    order_by_default: function() { 
     this.comparator = this._order_by_id; 
     this.sort(); 
    }, 
    _order_by_offers: function(ab) { 
     return ab.get('offers'); 
    } 
}); 

demostración: http://jsfiddle.net/ambiguous/Pjfq2/

+2

Te quería +1 incluso si esto no era correcto para el esfuerzo solo;) – ggozad

+0

@ggozad: Gracias . Me gusta enseñar a las personas cómo evitar errores y ayudarlos a corregir sus errores actuales. Y http://jsfiddle.net/ le quita mucho esfuerzo. –

+0

¡Muchas gracias, realmente aprecio el tiempo que ha dedicado a explicar todo esto! – Xrender

0

escribí encargo m étodo de la colección que se encargará de clasificar tanto ascendente como descendente y también ordena los registros con alfanumérica apropiada

var LetterVariables = Backbone.Collection.extend({ 



    initialize: function (id) { 

     //id of the table 
     this.id = id; 

     this.sortVar = "id"; //default sorting column 
     this.sOrder = "asc" //default sort order 
    }, 
    //comparator function that will create a descending and an ascending order tot he view 
    comparator: function (item,itemb) { 
     var a=item.get(this.sortVar); 
     var b=itemb.get(this.sortVar); 
     if (this.sOrder == "asc") { 
      return this.SortCustom(a, b); 
     } 
     return -this.SortCustom(a, b); 
    }, 
    SortCustom:function(a,b){ 
       if (isNaN(a)) { 
        if (isNaN(b)) { 
         if (a > b) return 1; // before 
         if (b > a) return -1; // after 
         return 0; 
        } 
        return 1; 
       } 
       if (isNaN(b)) { 
        return -1; 
       } 
       if (+a > +b) return 1; // before 
       if (+b > +a) return -1; // after 
       return 0; 
    }, 
    Sort: function (by, order) { 

     this.sOrder = order; 
     this.sortVar = by; 
     this.sort(); 
    }}); 

// se puede ordenar mediante el método de "Ordenar" (mirar de cerca S mayúscula para el método de clasificar)

Cuestiones relacionadas