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.
_.extendtakes multiple objects , copies properties onto first one.backbone.view.extendtakes single object, , returns new constructor function construct object has object prototype, , inherits prototype of first constructorextendcalled 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