Задать вопрос
Пользователь пока ничего не рассказал о себе

Достижения

Все достижения (1)

Наибольший вклад в теги

Все теги (9)

Лучшие ответы пользователя

Все ответы (3)
  • Сортировка/фильтрация в Backbone?

    @xaseros
    Я считаю что полностью заново рендерить коллекцию при сортировке это вообще шаг назад от идеологии MVC. рендерить заново надо только то что изменилось.

    При сортировке или фильтрации, мы можем использовать умное обновление коллекций с сервера. Оно будет вызывать соответствующие события add, remove, change. На любой списочный интерфейс я завожу 4 "класса", например: CommentListViewClass, CommentItemViewClass, CommentCollectionClass, CommentModelClass.

    CommentCollection передаем в CommentListView, и вызываем CommentCollection.fetch()
    Собственно вся соль делается в CommentListView, его и прифожу.
    var CommentsListViewClass = Backbone.View.extend({
            initialize: function(options){
                this.templateData = options && options.templateData || {};
                this.listenTo(this.collection, "add", this.renderItem);
                this.listenTo(this.collection, "add remove sync", this.renderUpdate);
                this.listenTo(this.collection, "sync", this.resortItems);
                
                this.itemViews = [];
            },
            render: function(){
                this.$el.empty();
            },
            renderUpdate: function(){
                $('.comments_count').html(this.collection.length);
            },
            resortItems: function(){
                this.collection.each(_.bind(function(m,i){
                    var viewEl = this.$("."+m.cid);
                    this.placeItem(viewEl, m);
                }, this));
            },
            placeItem: function(itemEl, model){
                var index = _.indexOf(this.collection.models, model);
                //console.log(index, itemEl,model);
                if(index == 0){
                    console.log("#"+ index ,model.id, 'ontop');
                    this.$el.prepend(itemEl);
                } else {
                    var pIndex = index-1;
                    var cid = this.collection.models[pIndex].cid;
                    this.$el.find('.'+cid).after(itemEl);
                    console.log("#"+ index, model.id, "after " + this.collection.models[pIndex].id );
                }
            },
            renderItem: function(model, collection, options){
                var item = new CommentsItemViewClass({
                    model: model,
                    templateData: this.templateData
                });
                
                var itemEl = item.render();
                this.placeItem(itemEl, model);
            }
        });


    При добавлении новой модели в коллекцию, мы инициализируем новый вид элемента списка, передавая ему эту же модель. Это делает метод render_item.

    var item = new CommentsItemViewClass({
                    model: model,
                    templateData: this.templateData
                });
                //получим DOM-элемент вида
                var itemEl = item.render();


    Далее у каждого DOM-элемента (this.el) созданного вида добавляется класс (или любой другой атрибут) с cid той модели которую он отображает (это нужно сделать в шаблоне элемента). Затем нужно определить индекс (позицию) модели в коллекции, и разместить этот элемент под элементом вида предыдущей модели в коллекции (ну или воткнуть на самый верх если таковой не найден), этим далее и занимается метод placeItem .

    var index = _.indexOf(this.collection.models, model);
                //console.log(index, itemEl,model);
                if(index == 0){
                    this.$el.prepend(itemEl);
                } else {
                    var pIndex = index-1;
                    //cid предыдущей модели
                    var cid = this.collection.models[pIndex].cid;
                    this.$el.find('.'+cid).after(itemEl);
                }


    Аналогично при полном обновлении коллекции после sync, только пробежаться надо по всем моделям коллекции, дабы расставить все элементы по местам. Это уже resortItems.

    this.collection.each(_.bind(function(m,i){
                    var viewEl = this.$("."+m.cid);
                    this.placeItem(viewEl, m);
                }, this));
    Ответ написан
    Комментировать
  • Как устроен AngularJS?

    @xaseros
    На месте этих скобок, которые скорее всего ищутся либо регулярками, дибо собственным конечным автоматом, вставляется текстНод - объект DOM, который в свою очередь специальным объектом-биндером "связывается" с объектом scope. Биндер подписан на изменения scope, и при получении такого события, обновляет содержимое textNode.

    Вместо textNode может быть любой другой элемент DOM, и может меняться не только текстсовое содержимое элемента, но и его атрибуты например.
    Ответ написан
    4 комментария

Лучшие вопросы пользователя

Все вопросы (5)