Nageswaran
Nageswaran

Reputation: 7671

Calling super class method in Backbone

var BaseView = Backbone.View.extend({
    localizedTemplate : function (element) {
        template = _.template(element.html());

        return function (data) {
            return template($.extend({}, data, resource));
        };
    }
});

var DerivedView = BaseView.extend({
   initialize: function (options) {
       this.model = options.model;

       this.template = function () {
         return this.localizedTemplate($("#someTemplate"));
       };
   },

   render: function () {
       var output = this.template(this.model.toJSON());
       this.$el.append(output);
       return this;
   }
});

Why the above code is not working? why I am not able to call the someFunction in DerivedView? is there any way to achieve this?

I am using Backbone latest version.

Upvotes: 0

Views: 288

Answers (2)

mu is too short
mu is too short

Reputation: 434695

When you do this:

this.template = function () {
    return this.localizedTemplate($("#someTemplate"));
};

You're assigning a function to this.template. Note that localizedTemplate also returns a function:

return function (data) {
    return template($.extend({}, data, resource));
};

That means that this.template is a function which returns a function and that second function is the one that wants this.model.toJSON() as an argument.

You're doing this:

var output = this.template(this.model.toJSON());

The function in this.template ignores its arguments and returns a function, that leaves you with this function:

function () {
    return this.localizedTemplate($("#someTemplate"));
}

in output. You probably think output is a chunk of HTML at this point so you hand that to append:

this.$el.append(output);

But output is a function and what does append do when called with a function as its argument? jQuery calls that function like this:

function(index, html)
Type: Function()
A function that returns an HTML string, DOM element(s), or jQuery object to insert at the end of each element in the set of matched elements. Receives the index position of the element in the set and the old HTML value of the element as arguments. Within the function, this refers to the current element in the set.

So the output function will be called by jQuery's append and append will supply arguments that the compiled template function doesn't understand. The result is a big pile of confusion.

If you really want to do things like this then you'll want to call all the functions yourself so that you can get the right arguments to the right places:

var output = this.template()(this.model.toJSON());
// -----------------------^^

Demo: http://jsfiddle.net/ambiguous/YyJLR/

Or better, don't bother with all the extra wrappers at all. Say this in your view's initialize:

this.template = this.localizedTemplate($("#someTemplate"));

and then this in render:

var output = this.template(this.model.toJSON());

Demo: http://jsfiddle.net/ambiguous/BQjhS/

Also note that you don't need to this.model = options.model, the view constructor will do that for you:

There are several special options that, if passed, will be attached directly to the view: model, collection, el, id, className, tagName and attributes.

Upvotes: 2

Bart
Bart

Reputation: 6814

var DerivedView = BaseView.extend({
   someVariable: function(someData) {
      return this.someFunction(someData);
   }
});

Upvotes: 0

Related Questions