Search code examples
javascriptbackbone.jsunderscore.jssplunk

Javascript: Overwriting the prototype of a Backbone model


I want to overwrite the prototype of a Backbone model using underscore.js. This is my code:

_.extend(TableView.prototype, {
    el: $("#" + this.id + "_div"),
});

In summary, I want that by default the model is attached to a html element with an id equal to the model's id plus "_div". The model's id is TableView's attribute id, and I try to access the model using this. The problem is that I get the error: "this is undefined". Why?

PS: I know that the correct way is to extend the model in a new one. I want to overwrite the original one because Backbone's extend() method seems to be not like class inheritance, and my_new_object instanceof TheOldModel return false. Anyway, I get the same error with TableView.extend() too.

PPS: I'm extending some Splunk views.


Solution

  • When your code snippet is evaluated, this has no specific meaning and is set to whatever the context is. It would only make sense in an instance context which happens way later.

    If you want to set a dynamic el, provide a function to be evaluated when you instantiate a view:

    var TableView = Backbone.View.extend({
        el: function() {
            return '#'+this.id+'_div';
        }
    });
    
    var v = new TableView({id: 'x'});
    console.log(v.$el.text());
    

    http://jsfiddle.net/nikoshr/bcfhqq18/

    Or, if you prefer to modify the prototype

    TableView.prototype.el = function() {
        return '#'+this.id+'_div';
    }
    

    http://jsfiddle.net/nikoshr/bcfhqq18/2/

    Finally, note that extending a class via Backbone sets the prototype chain and instanceof should be true when testing against an ancestor class:

    var TableView = Backbone.View.extend({
    });
    var DeepTableView = TableView.extend({
        el: function() {
            return '#'+this.id+'_div';
        }
    });
    
    var v = new DeepTableView({id: 'x'});
    
    console.log(v instanceof Backbone.View); // true
    console.log(v instanceof TableView); // true
    console.log(v instanceof DeepTableView); // true
    

    http://jsfiddle.net/nikoshr/bcfhqq18/3/