2012-08-09 24 views
7

El método actual que estoy usando es filtrar una colección, que devuelve una matriz, y utilizarBackbone.js: ¿forma correcta de filtrar una colección?

collection.reset(array) 

para volver a llenarla. Sin embargo, esto modifica la colección original, así que agregué una matriz llamada "originalCollectionArray" que realiza un seguimiento del estado inicial de la colección. Cuando no hay filtrado está activo simplemente uso

collection.reset(originalCollectionArray) 

Pero entonces, necesito hacer un seguimiento de la adición y la eliminación de los modelos de la colección real, por lo que hice esto:

// inside collection 
initialize: function(params){ 
    this.originalCollectionArray = params; 
    this.on('add', this.addInOriginal, this); 
    this.on('remove', this.removeInOriginal, this); 
}, 
addInOriginal: function(model){ 
    this.originalCollectionArray.push(model.attributes); 
}, 
removeInOriginal: function(model){ 
    this.originalTasks = _(this.originalTasks).reject(function(val){ 
     return val.id == model.get('id'); 
    }); 
}, 
filterBy: function(params){ 
    this.reset(this.originalCollectionArray, {silent: true}); 
    var filteredColl = this.filter(function(item){ 
     // filter code... 
    }); 
    this.reset(filteredColl); 
} 

Esto se está convirtiendo rápidamente engorroso como trato de implementar otros trucos relacionados con la manipulación de la colección, como la clasificación. Y francamente, mi código parece un poco hacky. ¿Hay una manera elegante de hacer esto?

Gracias

+1

¿Hay alguna razón por la que no sólo se utiliza 'fetch ({añadir: true}) 'en lugar de restablecer? Parece que esto es lo que intentas lograr. No estoy seguro de lo que está haciendo su función 'filter', pero siempre puede pasar' {data: {...}} 'para recuperarla también. – bvulaj

+0

Si entiendo correctamente, quiere que coloque originalCollectionArray y sus eventos por completo y busque los datos originales cada vez que hago un filtro/clasificación (la ordenación se ejecuta en los datos filtrados, por lo que cada clasificación también debe buscar y filtrar). El caso es que el filtro se activa a partir de la entrada del usuario. Pensé que desperdiciaría demasiado recurso. Sin embargo, solo estoy hablando hipotéticamente. – chenglou

Respuesta

11

Se puede crear una colección como una propiedad de la colección principal que refleja el estado de los filtros:

var C = Backbone.Collection.extend({ 
    initialize: function (models) { 
     this.filtered = new Backbone.Collection(models); 
     this.on('add', this.refilter); 
     this.on('remove', this.refilter); 
    }, 

    filterBy: function (params){ 
     var filteredColl = this.filter(function(item){ 
      // ... 
     }); 

     this.filtered.params = params; 
     this.filtered.reset(filteredColl); 
    }, 

    refilter: function() { 
     this.filterBy(this.filtered.params); 
    } 
}); 

La colección primaria mantiene sus modelos lo filtros se ha dirigido y que se unen a la colección filtrada para saber cuándo ha ocurrido un cambio. Al vincular internamente los eventos de agregar y eliminar, puede volver a aplicar el filtro. Ver http://jsfiddle.net/dQr7X/ para una demostración.

1

El principal problema de su código es que está utilizando una matriz sin formato como original, en lugar de una colección. Mi código está cerca de la suya, pero usar sólo las colecciones, así como los métodos de añadir, eliminar y filtro funciona en el original:

var OriginalCollection = Backbone.Collection.extend({ 
    }); 
    var FilteredCollection = Backbone.Collection.extend({ 
    initialize: function(originalCol){ 
     this.originalCol = originalCol; 
     this.on('add', this.addInOriginal, this); 
     this.on('remove', this.removeInOriginal, this); 
    }, 
    addInOriginal: function(model){ 
     this.originalCol.add(model); 
    }, 
    removeInOriginal: function(model){ 
     this.originalCol.remove(model); 
    }, 
    filterBy: function(params){ 
     var filteredColl = this.originalCol.filter(function(item){ 
      // filter code... 
     }); 
     this.reset(filteredColl); 
    } 
    }); 
+0

Muchas gracias por la respuesta. – chenglou

Cuestiones relacionadas