Reputation: 149
I'm having an issue with a helper function inside my Backbon.js View. When it's run, it dies with the following error message about the first line of the "addCalc" function:
TypeError: this.getCalcValue is not a function
It's really puzzling because in the "initialize" function defined just above, all the functions seem to be defined. It feels like I'm calling the sibling method wrong, and the "initialize" method is an exception where "this" can be used to reference the object.
Is there something wrong/missing with the following code, or something I missed with the backbone documentation?
CalcView = Backbone.View.extend({
el: $("#calcView"),
initialize: function () {
this.resetCalc();
},
addCalc: function (model) {
var cost = this.getCalcValue(model.get('currentCost'));
var custom = this.getCalcValue(model.get('customProgram'));
var variables = { id: model.get('id'),
category: model.get('category'),
shortDesc: model.get('shortDescription'),
description: model.get('description'),
currentCost: cost,
customProgram: custom,
};
var template = _.template($('#calc_template').html(), variables);
$("#calc_payload").append(template);
},
resetCalc: function(models) {
$("#calc_payload tr").remove();
},
removeCalc: function(model){
$("#calc_payload #" + model.get('id')).remove();
},
updateCalcs: function(model) {
var cost = model.get('currentCost');
var custom = model.get('customProgram');
$("#" + model.get("id") + " .currentCost").text(this.getCalcValue(cost));
$("#" + model.get("id") + " .customProgram").text(this.getCalcValue(custom));
/*var currentCostSum = 0;
var customProgramSum = 0;
$("#calc_payload .currentCost").each(function() {
var temp = Number(($(this).text()).replace(/[^0-9\.]+/g, ""));
if (!isNaN(temp))
currentCostSum += temp;
});
$("#calc_payload .customProgram").each(function() {
var temp = Number(($(this).text()).replace(/[^0-9\.]+/g, ""));
if (!isNaN(temp))
customProgramSum += temp;
});
$("#calc_footer .currentCost").text("$" + ((currentCostSum == 0) ? " -- " : CurrencyFormatted(currentCostSum.toFixed(2))));
$("#calc_footer .customProgram").text("$" + ((customProgramSum == 0) ? " -- " : CurrencyFormatted(customProgramSum.toFixed(2))));*/
},
getCalcValue: function(value) {
if (typeof value == 'string' || value instanceof String)
return value.toString();
else if (isNaN(value))
return "$ -- ";
else
return "$" + value.toFixed(2);
},
});
The code that executes the "addCalc" function is driven by a backbone collection. Basically, when the collection is added to, the CalcView.addCalc is called
Calculations = Backbone.Collection.extend({
model: Calculation,
//This is our Friends collection and holds our Friend models
initialize: function (models, options) {
this.on("add", options.onAdd);
this.on("remove", options.onRemove);
this.on("reset", options.onReset);
//Listen for new additions to the collection and call a view function if so
}
});
//This is where addCalc is used.
var calcview = new CalcView();
var calc_collection = new Calculations( null, {
onAdd: calcview.addCalc,
onRemove: calcview.removeCalc,
onReset: calcview.resetCalc
});
Upvotes: 0
Views: 2420
Reputation: 1638
When you bind events on collection
you can send the context
as third argument. Try sending one more option property as your calcview
and pass it as context.
this.on("add", options.onAdd, options.calcview);
this.on("remove", options.onRemove, options.calcview);
this.on("reset", options.onReset, options.calcview);
Upvotes: 0
Reputation: 19098
In your initialize
function add this line of code:
_.bindAll(this,'addCalc');
This will bind this
to be your CalcView
for the addCalc
function. You can put multiple comma separated method names in there if you need to bind more than one function...
See Underscore's documentation on it here.
Upvotes: 2