Backbone过滤器收集和渲染它

时间:2014-09-18 18:06:30

标签: backbone.js backbone-views backbone-collections backbone-paginator

我对骨干仍然很陌生,所以如果我正在做的事情有任何重大错误,我很抱歉。

我尝试做的事情似乎非常简单:从数据库中获取一组模型并对其进行一些过滤。我们假设我们正在尝试过滤酒店。一旦我有我的主要收藏品,我想过滤它们的价格,星星等等(几乎你可以在yelp或tripadvisor中找到的东西) - 当然,我想"重置&#34 ;用户取消选中不同的复选框后,过滤器。

到目前为止,我有3个观点:   - 基于面板的一个视图,其中将显示结果   - 基于代表每个项目(每个酒店)的模板的一个视图   - 我想要使用的所有过滤器都有一个视图。

我遇到的问题是我能够将我的集合保持在这样的状态,即我能够恢复我的过滤器或使用新集合刷新视图。 你能帮我理解我的问题所在吗?我该怎么办?

<script>
// model
var HotelModel = Backbone.Model.extend({});

// model view
var ItemView = Backbone.View.extend({
    tagName : 'div',
    className : 'col-sm-4 col-lg-4 col-md-4',
    template : _.template($('#hotelItemTemplate').html()),

    initialize : function() {
        this.model.bind('change', this.render, this);
        this.model.bind('remove', this.remove, this);
    },

    render : function() {
        this.$el.html(this.template(this.model.toJSON()));
        return this;
    }
});

//view list
var HotelListView = Backbone.View.extend({
    el : '#paginated-content',

    events : {
        "scroll" : "fetch"
    },

    initialize : function(options) {
        var items = this.collection;
        items.on('add', this.add, this);
        items.on('all', this.render, this);         
    },

    add : function(item) {
        var view = new ItemView({
            model : item
        });
        $('#paginated-content').append(view.render().el);
    },

    fetch : function() {
        this.collection.getNextPage();
    }
});

// filterign menu
var FilteringView = Backbone.View.extend({
    el : '#filtering',

    // just examples of one of the filters that user can pick
    events : {
        'click #price_less_100 ' : 'updateValue',
        'click #five_stars ' : 'updateStars',
    },

    template : _.template($('#filteringTemplate').html()),

    initialize : function() {
        this.collection.on('reset', this.render, this);
        this.collection.on('sync', this.render, this);
    },

    render : function() {
        this.$el.html(this.template);
        return this;
    },

    updateValue : function(e) {

        //this is something I'm not using at the moment but that it contains a copy of the collection with the filters
        var filtered = new FilteredCollection(coursesPaginated);

        // if is checked
        if (e.currentTarget.checked) {
            var max = 100;

            var filtered2 = _.filter(this.collection.models, function(item) {
            return item.get("price") < max;
            });

            //not used at the moment
            //filtered.filterBy('price', function(item) {
            //  return item.get('price') < 100;
            //});

            //this does not work
            //this.collection.reset(filtered2);

            //so I do this
            this.collection.set(filtered2);

        } else{
              // here, i would like to have something to put the collection in a state before this filter was applied           

          //something that I do not use at the moment
          //filtered.removeFilter('price');
        }

    },
    updateStars : function(e) {
       //do something later
    }
});

// collection
var HotelCollection = Backbone.PageableCollection.extend({
    model : HotelModel,

    // Enable infinite paging
    mode : "server",

    url : '{{url("/api/hotels")}}',

    // Initial pagination states
    state : {
        pageSize : 15,
        sortKey : "updated",
        order : 1
    },

    // You can remap the query parameters from `state` keys from
    // the default to those your server supports
    queryParams : {
        totalPages : null,
        totalRecords : null,
        sortKey : "sort"
    },

    parse : function(response) {
        $('#hotels-area').spin(false);
         this.totalRecords = response.total;
         this.totalPages = Math.ceil(response.total / this.perPage);
        return response.data;
    }
});

$(function() {
    hotelsPaginated = new HotelCollection();

    var c = new HotelListView({
        collection : hotelsPaginated
    });


    $("#paginated-content").append(c.render().el);
    hotelsPaginated.fetch();
}); 

在我看来,使用骨干进行这样的过滤并不容易。如果有人有其他建议,请做。

谢谢!

1 个答案:

答案 0 :(得分:0)

我的解决方案:

  1. 定期从服务器取出的主要收集。
  2. 过滤后的集合,每次使用过滤时都会重置。
  3. 用于呈现过滤集合的主视图(示例new MainView({collection:filteredCollection};))此外必须有 收集处理程序&#39;重置&#39;事件。
  4. 过滤视图,其中包含一个包含过滤器值的模型,并使用新值触发Filtered Collection重置。
  5. 易于上手。 很抱歉没有代码示例,没有工作)