I am trying to write a Backbone view for an object browser which is designed to be implemented in several places with different object types and slightly different operation.
I have tried simply extending the backbone view in my browser and then extending the browser in my implementation however this leaves me with some properties which are shared. This is an undesired effect as the data is appended to all implementations with every browser creation.
Could someone shed light on a way to solve this problem or perhaps an alternative solution?
Here are some code examples to give you a better idea of how it currently stands:
var BrowserView = Backbone.View;
_.extend(BrowserView.prototype, Backbone.View.prototype, {
className: 'browser',
collections: [],
events: {
},
_events:{
},
initialize: function () {
this._initialize();
},
render: function () {
this._render();
},
_initialize: function () {
this.container = $( this.make('div', {class: 'container'} ) );
this.$el.append(this.container);
if ( this.options.collections ) {
this.collections = [];
_.each(this.options.collections, this.add, this);
}
_.extend(this.events, this._events);
this.delegateEvents();
},
_render: function () {
this.container.empty();
_.each(this.collections, function (view) {
this.container.append(view.el);
view.render();
}, this);
}
});
BrowserView.extend = Backbone.View.extend;
var ContactBrowserView = BrowserView.extend({
});
EDIT My issue is that the sub classes are sharing the collections property. Here is an example of my own solution which initialises the collections property through an inherited method. jsfiddle/JhZXh/3
I am trying to write a Backbone view for an object browser which is designed to be implemented in several places with different object types and slightly different operation.
I have tried simply extending the backbone view in my browser and then extending the browser in my implementation however this leaves me with some properties which are shared. This is an undesired effect as the data is appended to all implementations with every browser creation.
Could someone shed light on a way to solve this problem or perhaps an alternative solution?
Here are some code examples to give you a better idea of how it currently stands:
var BrowserView = Backbone.View;
_.extend(BrowserView.prototype, Backbone.View.prototype, {
className: 'browser',
collections: [],
events: {
},
_events:{
},
initialize: function () {
this._initialize();
},
render: function () {
this._render();
},
_initialize: function () {
this.container = $( this.make('div', {class: 'container'} ) );
this.$el.append(this.container);
if ( this.options.collections ) {
this.collections = [];
_.each(this.options.collections, this.add, this);
}
_.extend(this.events, this._events);
this.delegateEvents();
},
_render: function () {
this.container.empty();
_.each(this.collections, function (view) {
this.container.append(view.el);
view.render();
}, this);
}
});
BrowserView.extend = Backbone.View.extend;
var ContactBrowserView = BrowserView.extend({
});
EDIT My issue is that the sub classes are sharing the collections property. Here is an example of my own solution which initialises the collections property through an inherited method. jsfiddle.net/JhZXh/3
Share Improve this question edited Oct 28, 2020 at 20:28 Eli asked Feb 23, 2012 at 1:24 EliEli 3691 gold badge5 silver badges12 bronze badges4 Answers
Reset to default 11I think I've figured out the answer to my own problem.
I believe the right way to achieve what I am looking for is to move the initialization of properties in to the initialize method provided by Backbone views. This way they are initialized
var BrowserView = Backbone.View.extend({
initialize: function () {
this.collections = [];
}
});
var FileBrowserView = BrowserView.extend({
initialize: function () {
BrowserView.prototype.initialize.apply(this);
this.collections.push({name: 'Example Collection' + Math.rand()});
}
});
var FileBrowserInstance1 = new FileBrowserView;
console.log(FileBrowserInstance1.collections);
var FileBrowserInstance2 = new FileBrowserView;
console.log(FileBrowserInstance2.collections);
http://jsfiddle.net/yssAT/2/
It's hard to see what exactly your goal is.
but this is how i see it if you have an view object
var myView = Backbone.View.extend({
foo: "bar"
});
and you have it extend the backbone.View... then you actually have a new view object with everything of backbone.view, and the extra options you give as parameters.
if you then go and create a second view, that extends your first one it will get everything from your first view, + it's own extras
var mySecondView = myView.extend({
foobar: "f00b@r"
});
if you would create an instance of the second view and log it's foo
property it will still hold "bar"
as value
var mySecondViewInstance = new mySecondView();
console.log("mySecondViewInstance.foo: ", mySecondViewInstance.foo);
console.log("mySecondViewInstance.foobar: ", mySecondViewInstance.foobar);
if i create a new instance of my first view, and change foo
into "changed-foo"
the log of foo
on mySecondViewInstance
will still be "bar"
var myViewInstance = new myView();
myViewInstance.foo = "changed-foo";
console.log("mySecondViewInstance.foo: ", mySecondViewInstance.foo);
console.log("mySecondViewInstance.foobar: ", mySecondViewInstance.foobar);
a JS-Fiddle to play around with it can be found here: http://jsfiddle.net/saelfaer/uNBSW/
Inherit from Backbone.View
doesn't work, or is quite complex.
You should create a common object, which every of your view will inherit from, ie :
var ViewInterface = {
events : { /* ... */ },
initialize : function (options) { /* ... */ },
otherFunction : function (options) { /* ... */ },
}
each of your view would extend from this object :
var BrowserView = Backbone.View.extend(_.extend(ViewInterface, {
anotherFunction : function (options) { /* ... */ },
})
var AnotherView = Backbone.View.extend(_.extend(ViewInterface, {
yetAnotherFunction : function (options) { /* ... */ },
})
This gist shows a better alternative: https://gist.github.com/2287018