Reputation: 7671
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
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
andattributes
.
Upvotes: 2
Reputation: 6814
var DerivedView = BaseView.extend({
someVariable: function(someData) {
return this.someFunction(someData);
}
});
Upvotes: 0