Eli
Eli

Reputation: 369

Backbone View Inheritance

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

Upvotes: 6

Views: 6764

Answers (4)

Eli
Eli

Reputation: 369

I 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/

Upvotes: 11

pedroteixeira
pedroteixeira

Reputation: 824

This gist shows a better alternative: https://gist.github.com/2287018

Upvotes: 2

jney
jney

Reputation: 1912

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) { /* ... */ },
})

Upvotes: 3

Sander
Sander

Reputation: 13421

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/

Upvotes: 4

Related Questions