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 constructor extend 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

Popular posts from this blog

java - JavaFX 2 slider labelFormatter not being used -

Detect support for Shoutcast ICY MP3 without navigator.userAgent in Firefox? -

web - SVG not rendering properly in Firefox -