Как стать автором
Поиск
Написать публикацию
Обновить

Backbone. Несколько нюансов

Несколько нюансов работы с backbone, вызывающих затруднения у новичков.

Атрибут является коллекцией или моделью


Обычно атрибуты модели имеют простые типы (строка или число). Но иногда необходимо, что бы атрибут был моделью или коллекцией. Например, атрибут «frends» в данной модели должен быть коллекцией:

appTest.Models.modelMan = Backbone.Model.extend({
	'default':{
		...
		frends:{}
	}
})


Но если вы сфетчите данные, то атрибут «frends» будет просто объектом. Для того, что бы преобразовать его в коллекцию, переопределяем метод «set»:

set: function(attributes, options){     
      if(!(attributes.frends instanceof appTest.Collections.listMan)) {
          attributes.frends = new appTest.Collections.listMan (attributes.frends);
      }

      return Backbone.Model.prototype.set.call(this, attributes, options);
},


Преобразование модели, содержащей «сложный» атрибут в JSON


Следующая проблема, которая возникает при использовании «сложных атрибутов» — это преобразование таких объектов в json. Для этого переопределяем функцию toJSON у объекта, содержащего такой атрибут:

toJSON: function(){
    var json = _.clone(this.attributes);
    for(var attr in json) {
         if((json[attr] instanceof Backbone.Model) || (json[attr] instanceof Backbone.Collection)) {
             json[attr] = json[attr].toJSON();
         }
    }
    return json;
}


Для всех записей коллекции устанавливаем одно значение


У модели коллекции есть атрибут 'obj_type'. Для того, чтобы быстро изменить этот атрибут во всех объектах:

setObjType: function(idObjType){
   this.invoke('set',{'obj_type':idObjType})
},


Действие при удаление объекта


Предположим, у нас во вьюхе обрабатывается resize всего окна. Разумеется, при удалении объекта нужно отписаться от события:

appTest.Views.Main = Backbone.View.extend({
	initialize: function(){
		$(window).on('resize', _.bind(this.eventWindowResize, this));
	}

	remove: function() {
        	$(window).off("resize", this.eventWindowResize);
	        Backbone.View.prototype.remove.apply(this, arguments);
	},

})


Несколько роутеров на одной странице


К сожалению, роутер на странице может быть один. Но можно костыльнуть и вызывать дополнительный роутер из основного. Для этого:

  1. В основном роутере создаем список внешних роутеров (extraRouter);
  2. В основном роутере пишем функцию (addRouter), который будет заносить в список внешних роутеров и регистрировать новые правила из этого роутера на наш основной роутер.


appMainPage.Controller.main = Backbone.Router.extend({
    extraRouter: {},

    /**
     * Добавить внешний роутер<br>
     * Все события, которые нет у нас будут прописан на аналогичную функцию с префиксом
     * @param rout Роутер
     * @param prefix Под какти именем фигурирует
     */
    addRouter: function(rout, prefix){
        this.extraRouter[prefix] = rout;

        for(var rules in rout.routes) {
            var name = rout.routes[rules];
            if(this[name] == undefined){
                var nameFun = prefix + '_' + name;
                if(this[nameFun] == 'undefined')
                    console.log('Нет метода ' + nameFun);
                else
                    this.route(rules, nameFun);
            }
        }
    },

    /**
     * Показать новость
     * Вызывается из внешнего роутера	
     * @param idnews
     */
    news_show_news: function(idnews){
        this.renderMainPage();
        var router = this.extraRouter['news'];
        router.show_news(idnews);
    },

})


И само подключение:

appNews.route = new appNews.Controller.main;
appMainPage.route = new appMainPage.Controller.main;
appMainPage.route.addRouter(appNews.route, 'news');
        
if(!Backbone.History.started)
	Backbone.history.start();
Теги:
Хабы:
Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.