Backbone.js отображает коллекцию сброса с одним представлением

Я пытаюсь отобразить отфильтрованную коллекцию из одного представления, используя поле выбора, используя свойство сброса. Первая проблема заключается в том, что поле выбора и отображаемый контент должны отображаться в одном и том же div, чтобы работать. Это нормально? Вторая проблема заключается в том, что вместо отображения только отфильтрованных результатов он добавляет отфильтрованную коллекцию в конец отображаемого содержимого, а не заменяет его. конец всей коллекции. Вот мой пример кода ниже:

(function($) {

  var images = [
       { tags: "Fun", date : "April 3, 2012", location : 'Home', caption : 'Having fun with my lady'},
       { tags: "Chillin", date : "April 4, 2012", location : 'Home', caption : 'At the park with my lady'},
       { tags: "Professional", date : "April 5, 2012", location : 'Home', caption : 'At the crib with my lady'},
       { tags: "Education", date : "April 6, 2012", location : 'Home', caption : 'Having fun with my baby'},
       { tags: "Home", date : "April 3, 2012", location : 'Home', caption : 'Having fun with my lady'},
       { tags: "Professional", date : "April 4, 2012", location : 'Home', caption : 'At the park with my lady'},
       { tags: "Fun", date : "April 5, 2012", location : 'Home', caption : 'At the crib with my lady'},
       { tags: "Chillin", date : "April 6, 2012", location : 'Home', caption : 'Having fun with my baby'},
       { tags: "Fun", date : "April 3, 2012", location : 'Home', caption : 'Having fun with my lady'},
       { tags: "Education", date : "April 4, 2012", location : 'Home', caption : 'At the park with my lady'},
       { tags: "Personal", date : "April 5, 2012", location : 'Home', caption : 'At the crib with my lady'},
       { tags: "Personal", date : "April 6, 2012", location : 'Home', caption : 'Having a play date'}
    ];


var Item = Backbone.Model.extend({
    defaults : {
        photo : 'http://placehold.it/200x250'
    }
});

var Album = Backbone.Collection.extend({
    model : Item
});

var ItemView = Backbone.View.extend({
el : $('.content'),

   initialize : function() {
        this.collection = new Album(images);
        this.render();
        $('#filter').append(this.createSelect());
        this.on("change:filterType", this.filterByType);
        this.collection.on('reset', this.render, this);
    },
    template : $('#img_container').text(),
    render : function() {
        var tmpl = _.template(this.template);
        _.each(this.collection.models, function (item) {
           this.$el.append(tmpl(item.toJSON()));                   
        },this);
},

events: {
    "change #filter select" : "setFilter"
},

 getTypes: function () {
    return _.uniq(this.collection.pluck("tags"), false, function (tags) {
        return tags.toLowerCase();
        });
},

createSelect: function () {
    var filter = this.$el.find("#filter"),
        select = $("<select/>", {
            html: "<option>All</option>"
        });

    _.each(this.getTypes(), function (item) {
        var option = $("<option/>", {
            value: item.toLowerCase(),
            text: item.toLowerCase()
        }).appendTo(select);
    });
    return select;
},

setFilter: function (e) {
   this.filterType = e.currentTarget.value;
   this.trigger("change:filterType");
},

filterByType: function () {
    if (this.filterType === "all") {
        this.collection.reset(images);
    } else {
        this.collection.reset(images, { silent: true });
        var filterType = this.filterType,
            filtered = _.filter(this.collection.models, function (item) {
            return item.get("tags").toLowerCase() === filterType;   
        });   
       this.collection.reset(filtered);
    }
}

}); 

var i = new ItemView();


})(jQuery);

person Teeman    schedule 17.05.2012    source источник


Ответы (1)


Не видя вашей разметки, трудно сказать наверняка, но я подозреваю, что причина, по которой ваш выбор должен быть в одном и том же div, заключается в том, что когда вы связываете события в магистрали с помощью хэша событий, он использует его el в качестве корневого элемента для делегирования события.

Что касается того, почему ваша коллекция только добавляется, а не заменяется, я не вижу, чтобы вы где-либо очищали текущее содержимое, у вас должно быть в начале вашего метода рендеринга что-то вроде строк this.$el('.itemCnt').empty().

Отдельный момент: вы можете подумать о том, чтобы иметь представление для каждого из ваших элементов и объект для их кэширования, тогда каждый раз, когда фильтр изменяется, вместо сброса вашей коллекции вы можете отсоединять все элементы и повторно присоединять отфильтрованные элементы без повторного создания их разметки.

Например, что-то в духе

var ItemView = Backbone.View.extend({
   el : $('.content'),
   _views: {},
   //...

   add: function(item) {
     var view = new ItemView({model: item});
     this._views[item.cid] = view;
   }

   render: function (filteredItems) {
      this.$el.find('.ItemCnt .item').detach();

    var frag = document.createDocumentFragment();

      _.each(filteredItems, function(item) {
        frag.appendChild(this._views[item.cid].el);
     }
       this.$el.find('.ItemCnt').append(frag);
   }
person Jack    schedule 17.05.2012
comment
Это сделало трюк! спасибо куча! Я тоже попробую то, что вы предложили. так что это делает больше, так как использовать основной вид, который я вижу. Спасибо еще раз! - person Teeman; 17.05.2012
comment
Если ответ решает ваш вопрос, возможно, вы захотите принять его, поставив галочку слева от него. - person Jack; 17.05.2012