Коллекция магистральных фильтров и их рендеринг

Я все еще новичок в магистрали, так что извините, если есть какая-то грубая ошибка в том, что я делаю.

То, что я пытаюсь сделать, кажется очень простым: получить коллекцию моделей из БД и сделать несколько фильтров на ней. Допустим, мы пытаемся отфильтровать отели. Как только у меня будет моя основная коллекция, я хотел бы отфильтровать их по цене, звездам и т. Д. (В значительной степени то, что вы можете найти в yelp или tripadvisor или около того) - и, конечно, я хочу "сбросить" фильтры, как только пользователь снимает флажки.

Пока у меня есть 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 ответ

Мое решение для этого:

  1. Основная коллекция, которая периодически загружается с сервера.
  2. Фильтрованная коллекция, которая сбрасывается каждый раз, когда вы используете фильтрацию.
  3. Основное представление, которое использовалось для визуализации отфильтрованной коллекции (пример new MainView({collection: FilterCollection};)) Также должен быть обработчик для события сброса коллекции.
  4. Представление фильтра, в котором есть модель, содержащая значения фильтра, и которое запускает сброс фильтрованной коллекции с новыми значениями.

Все легко. Извините за отсутствие примеров кода, не на работе)

Другие вопросы по тегам