Backbone.js - Correct way of filtering and displaying collection data in a view

前端 未结 3 939
栀梦
栀梦 2020-12-22 16:38

I have got a huge list of tasks loaded on the start.
I want to show them depending on selected list / inbox, so that there won\'t be additional loadings for each list.

相关标签:
3条回答
  • 2020-12-22 16:48

    one quick amendment to you solution, you are using

    $(this.el).html('');
    

    My understanding is your the views and related event bindings will still exist in the browser memory, so you ideally need to use view.remove() on the TaskView to correctly clear the event bindings as well as the html.


    This is a slightly different take on the answer as I have been looking for a solution to a similar problem, hope this may be of help to others.

    My problem: - to filter a complete collection by attributes of the model. eg. a user clicks the models view, gets a list of (some of) the attributes, selecting an attribute filters the collection to only show ones with the same value.

    The route I am taking is by calling a method on the collection from the view, in my case the view is specific to a model so:

    this.model.collection.myFilter(attr,val);
    

    where attr is an attribute of the model associated with the collection, then in the filter something like

    myFilter: function(attr, val){
        var groupByAttr = this.groupBy(function(article){
            var res = (val === undefined)? true : (article.get(attr) == val);
            article.set({selected:res});
            return res;
        });
        return groupByAttr;
    }
    

    I have used ._groupBy as this returns 2 arrays (positive / negative) that may be of use. By setting the mode attribute "selected", and binding to this in the model view I can easily toggle a class which shows or hides the view.

    if(val === undefined) is added as a simple way of clearing a filter by calling the same method without a value.

    0 讨论(0)
  • 2020-12-22 16:52

    I think you need to use another collection. For example, in your inbox, do this:

    inbox: function(){
        currentCollection = new TasksCollection(tasks.inbox());
    }
    

    I haven't tested this but when you do a .reset(); you are removing all your models and loading the ones passed in.

    0 讨论(0)
  • 2020-12-22 17:12

    @sled there's typos in the code you posted, see comments inline. Did you post this as a project somewhere?

    // add models
    add: function(models, options) {
      // TYPO: next line was missing, so single models not handled.
      models = _.isArray(models) ? models.slice() : [models];
    
      var self = this;
    
      models = _.filter(models, this.filter);
    
      // return if no models exist
      // TYPO: returned undefined, so was not chainable
      if(models.length == 0) { return this; }
    
      // actually add the models to the superset
      this.superset.add(models, options);
      return this;
    },
    
    // remove models
    remove: function(models, options) {
      // TYPO: next line was missing, so single models not handled.
      models = _.isArray(models) ? models.slice() : [models];
    
      // remove model from superset
      this.superset.remove(_.filter(_.filter(models, function(cm) {
        // TYPO: not 'm != null', causes error to be thrown
        return cm != null;
      }), this.filter), options);
      // TYPO: missing return so not chainable
      return this;
    },
    
    0 讨论(0)
提交回复
热议问题