@MatenkaAndrii
Front-end developer

Как сохранить вложенную модель в localStorage (Backbone + Backbone-relational.js)?

Структура:
1f8849147d8b40a7899ca54c5fe6ef72.jpg

Демо: html.te.ua/builder
Кнопки Add Row и Add Column доданы только для теста.
Добавление модели Row в коллекцию работает отлично. Сохранение моделей Row в localStorage работает исправно. Если закрыть и открыть страницу видно что Row сохраняются в localStorage. А вот если добавить Column (в нашем случае в Модель Row get("id") == "c4" ) видно что хтмл добавляется но после закрытия страницы модель Column пропадает и не сохраняется в localStorage joxi.ru/E2p1y9btB5pXvA

Помогите разобраться. Готов поблагодарить финансово за потраченное время и силы!

(function ($) {
	window.App = {
		Models: {},
		Collections: {},
		Views: {},
		Router: {}
	};
	// Template
	window.template = function(id) {
		return _.template ( $( id ).html() );
	};
	// RowModel
	App.Models.Row = Backbone.RelationalModel.extend({
		relations: [
			{
				type: Backbone.HasMany,
				key: 'columns',
				relatedModel: 'App.Models.Column',
				includeInJSON: Backbone.Model.prototype.idAttribute,
				collectionType: 'App.Collections.Columns',
				reverseRelation: {
					key: 'columnIn'
				}
			}
		],
		defaults: {
			columns:[],
			id: null,
			type: "row",
			name: "Row",
			settings: {
			// Some settings
			}
		},
	    initialize: function() {
		    if ( !this.get("id") ) {
		    	this.set({"id": this.cid});
		    }
	    }
	});
	// ColumnModel
	App.Models.Column = Backbone.RelationalModel.extend({
		relations: [
			{
				type: Backbone.HasMany,
				key: 'modules',
				relatedModel: 'App.Models.Module',
				includeInJSON: Backbone.Model.prototype.idAttribute,
				collectionType: 'App.Collections.Modules',
				reverseRelation: {
					key: 'moduleIn'
				}
			}
		],
		defaults: {
			modules: [],
			id: null
		},
		initialize: function() {
		    if ( !this.get("id") ) {
		    	this.set({"id": this.cid});
		    }
	    }
	});
	// ModuleModel
	App.Models.Module = Backbone.RelationalModel.extend({
		defaults: {
			id: null,
			type: null,
			parent: null,
			name: null,
			tag: null,
			content: null
		},
		initialize: function() {
		    if ( !this.get("id") ) {
		    	this.set({"id": this.cid});
		    }
	    }
	});
	// RowsCollection
    App.Collections.Rows = Backbone.Collection.extend({
    	model: App.Models.Row,
    	localStorage: new Backbone.LocalStorage("uni-page-builder")
    });

    // ColumnsCollection
    App.Collections.Columns = Backbone.Collection.extend({
    	model: App.Models.Column
    });

    // ModulesCollection
    App.Collections.Modules = Backbone.Collection.extend({
    	model: App.Models.Module
    });

	// PageBuilderView
	App.Views.PageBuilderView = Backbone.View.extend({
		el: $("#uni-page-builder"),
		initialize: function() {
			var rowsView = new App.Views.RowsView( {collection : App.rows} );
			this.$("#uni-rows").html( rowsView.render().el );
		},
		events: {
			"click #add-row" : "triggerAddRow",
			"click #add-column" : "triggerAddColumn"
		},
		triggerAddRow: function() {
			Backbone.trigger('event-addRow');
		},
		triggerAddColumn: function() {
			Backbone.trigger('event-addColumn');	
		}
	});

	// RowsView
	App.Views.RowsView = Backbone.View.extend({
		className: "uni-builder-content",
		initialize: function() {
			Backbone.on('event-addRow', this.addRow, this);
			Backbone.on('event-addColumn', this.addColumn, this);
			this.collection.on('add', this.renderRow, this );
			//this.collection.on('add:columns', this.fetch(), this);
		},
		render: function() {
			this.collection.each( this.renderRow, this );
			return this;
		},
		renderRow: function(row){
			var rowView = new App.Views.RowView({ model : row });
			this.$el.append( rowView.render().el );
		},
		addRow: function(){
			this.collection.create({
				columns:[],
				id: null,
				type: "row",
				name: "Row",
				settings: {
				// settings
				}
			});
		},
		addColumn: function(){
			this.collection.each( this.createColumn, this );
		},
		createColumn: function(row){
			if (row.get("id") == "c4") {
				column = new App.Models.Column({
					modules: [],
					id: null	
				});
				row.save({columns:column})   	
			}
		}
	});
	
	// RowView
	App.Views.RowView = Backbone.View.extend({
		template: template('#js-uni-row-tmpl'),
		overlayTemplate: template('#js-uni-row-overlay-tmpl'),
		initialize: function() {
			this.model.on('destroy', this.removeRow, this);
		},
		render: function(){
    		var element = this.template(this.model.toJSON());
	        	this.setElement(element);
	        var columns = this.model.get('columns'),
				columnsView = new App.Views.ColumnsView( {collection : columns} );
    		this.$el.find(".uni-row-content").append(columnsView.render().el);
    		return this;
		},
		events: {
			"mouseenter": "showRowOverlay",
			"mouseleave": "hideRowOverlay",
			"click .js-uni-row-remove": "destroyRow"
		},
		showRowOverlay: function(){
			if (!this.$el.hasClass("uni-block-overlay-active")) {
				var overlay = this.overlayTemplate(this.model.toJSON());
				this.$el.addClass("uni-block-overlay-active").append(overlay);
			}
		},
		hideRowOverlay: function(){
			this.$el.removeClass("uni-block-overlay-active").find(".uni-row-overlay").remove();
		},
		destroyRow: function () {
            this.model.destroy();
		},
		removeRow: function(){
			this.remove();
		}
	});

	// ColumnsView
	App.Views.ColumnsView = Backbone.View.extend({
		className: "uni-col-group",
		initialize: function() {
			this.collection.on('add', this.renderColumn, this );
		},
		render: function() {
			this.collection.each( this.renderColumn, this );
			return this;
		},
		renderColumn: function(column){
			var columnView = new App.Views.ColumnView({ model : column });
			this.$el.append( columnView.render().el );
		}
	});

	// ColumnView
	App.Views.ColumnView = Backbone.View.extend({
		template: template('#js-uni-col-tmpl'),
		render: function(){
    		var element = this.template(this.model.toJSON());
	        	this.setElement(element);
    		//this.$el.find(".uni-row-content").append(columnsView.render().el);
    		return this;
		}
	});
	App.rows = new App.Collections.Rows();
	App.rows.fetch().then(function(){
		var UniPageBuilder = new App.Views.PageBuilderView({collection: App.rows});		
	});

} (jQuery));
  • Вопрос задан
  • 184 просмотра
Пригласить эксперта
Ответы на вопрос 1
dpigo
@dpigo
Front-end developer
Так у вас модели Columns не сохраняются в localStorage совсем, откуда им взяться после перезагрузки? Вот смотрите как это реализуется: stackoverflow.com/questions/20408405/backbone-loca...
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы