javascript - Backbone View shouldn't have same data in different instances but does -
i have backbone view has following code within render function (note 3 console.log(that.ticketselector.attributes);
):
if(typeof this.ticketselector === 'undefined') { // todo: first fetch tickets this.ticketselector = new datatable({ collection: that.model.tickets, icon: "ticket", title: "tickets", customclasses: ["ticket", "subject-selector"], columns: [ {text: 'name', modelkey: "name", col: 1}, {text: 'date', modelkey: "date", col: 2}, {text: 'owner', modelkey: "owner", col: 3}, {text: 'description', modelkey: "description", col: 4} ] }); this.$('.subject-selectors').append(this.ticketselector.$el); this.ticketselector.render().resize(); } else { this.ticketselector.render().resize(); } console.log(that.ticketselector.attributes); if(typeof this.alarmselector === 'undefined') { // todo: first fetch tickets this.alarmselector = new datatable({ collection: that.model.alarms, icon: "warning-sign", title: "alarms", customclasses: ["alarm", "subject-selector"], columns: [ {text: 'name', modelkey: "name", col: 1}, {text: 'date', modelkey: "date", col: 2}, {text: 'owner', modelkey: "owner", col: 3}, {text: 'description', modelkey: "description", col: 4} ] }); this.$('.subject-selectors').append(this.alarmselector.$el); this.alarmselector.render().resize(); } else { this.alarmselector.render().resize(); } console.log(that.ticketselector.attributes); if(typeof this.taskselector === 'undefined') { // todo: first fetch tickets this.taskselector = new datatable({ collection: that.model.tasks, icon: "tasks", title: "tasks", customclasses: ["task", "subject-selector"], columns: [ {text: 'name', modelkey: "name", col: 1}, {text: 'date', modelkey: "date", col: 2}, {text: 'owner', modelkey: "owner", col: 3}, {text: 'description', modelkey: "description", col: 4} ] }); this.$('.subject-selectors').append(this.taskselector.$el); this.taskselector.render().resize(); } else { this.taskselector.render().resize(); } console.log(that.ticketselector.attributes);
in console see:
object {icon: "ticket", title: "tickets", columns: array[4], classes: array[2]} object {icon: "warning-sign", title: "alarms", columns: array[4], classes: array[2]} object {icon: "tasks", title: "tasks", columns: array[4], classes: array[2]}
where expect:
object {icon: "ticket", title: "tickets", columns: array[4], classes: array[2]} object {icon: "ticket", title: "tickets", columns: array[4], classes: array[2]} object {icon: "ticket", title: "tickets", columns: array[4], classes: array[2]}
here datatable view:
var datatable = backbone.view.extend({ tag: 'div', classname: 'data-table', initialize: function(opts) { if(typeof opts.parent !== 'undefined') { this.parent = opts.parent; } if(typeof opts.icon !== 'undefined') { this.attributes.icon = opts.icon; } if(typeof opts.title !== 'undefined') { this.attributes.title = opts.title; } if(typeof opts.columns !== 'undefined') { this.attributes.columns = opts.columns; } if(typeof opts.customclasses !== 'undefined') { this.attributes.classes = opts.customclasses; } }, attributes: {}, template: function() { var temp; $.ajax(root + 'templates/data-table.html', { success: function(data) { // console.log(data); temp = mustache.compile($(data).filter('#data-table-template').html()); }, async: false }); return temp; }(), events: { }, serialize: function() { var = this; return { root: root, icon: that.attributes.icon, title: that.attributes.title, columns: that.attributes.columns }; }, resize: function() { var = this; }, subview: [], render: function() { var = this; var html = this.template(this.serialize()); this.$el.html(html); if(that.attributes.classes) { _.each(that.attributes.classes, function(c) { that.$el.addclass(c); }); } this.collection.each(function(row) { tempview = new datatablerow({ model: row, parent: that, columns: that.attributes.columns }); that.subview.push(tempview); that.$('.tbody').append(tempview.$el); tempview.render(); }); this.$('.tbody').mcustomscrollbar({ scrollinertia: 0, }); return this; } }); var datatablerow = backbone.view.extend({ tag: 'div', classname: 'tr', initialize: function(opts) { var = this; if(typeof opts.parent !== 'undefined') { this.parent = opts.parent; } if(typeof opts.columns !== 'undefined') { var temp = {}; that.attributes.columns = _.map(opts.columns, function(col) { return { text: that.model.get(col.modelkey), col: col.col }; }); } }, attributes: { columns: [] }, template: function() { var temp; $.ajax(root + 'templates/data-table.html', { success: function(data) { // console.log(data); temp = mustache.compile($(data).filter('#data-table-row-template').html()); }, async: false }); return temp; }(), events: { }, serialize: function() { var = this; return { root: root, columns: that.attributes.columns }; }, resize: function() { var = this; }, render: function() { var = this; var html = this.template(this.serialize()); this.$el.html(html); return this; } });
i know around creating different views each data table, should work , @ loss why isn't. here? thanks.
edit: attempt understand better, here underscore extend function:
_.extend = function(obj) { each(slice.call(arguments, 1), function(source) { if (source) { (var prop in source) { obj[prop] = source[prop]; } } }); return obj; };
what makes these attributes attach prototype?
your attributes
{}
on prototype, shared across instances of object. need have attributes
object each instance.
instead of this:
var datatable = backbone.view.extend({ attributes: {} });
you need create new object on each initialization:
var datatable = backbone.view.extend({ attributes: {}, initialize: function(options){ this.attributes = {}; } });
as @muistooshort pointed out, have problem subviews
array , datatablerow.prototype.attributes
too. key-value pairs in object passed extend
placed on object's prototype, means new instances of object share attributes. how of functions end on each instance, means else too, make sure things initialized each instance.
edit
backbone.view.extend
unrelated _.extend
except happens use has helper other code.
_.extend
takes multiple objects , copies properties onto first one.backbone.view.extend
takes single object, , returns new constructor function construct object has object prototype, , inherits prototype of first constructorextend
called on.
https://github.com/jashkenas/backbone/blob/master/backbone.js#l1532
so had object this:
backbone.view
constructor when called create new object has backbone.view.prototype
prototype having standard view methods.
when var datatable = backbone.view.extend(newproto_obj)
, have this:
datatable
constructor when called create new object has prototype values newproto_obj
, , backbone.view.prototype
prototype of prototype.
this called prototype chain, , how javascript inheritance. when create new object, has no properties of own unless set backbone in constructor or initialize
functions. if attempt access property on object , not present, see if prototype has property name. because prototype object single common object shared across instances, modifying change every instance.
Comments
Post a Comment