I just want to fire an event when an input changes value using jQuery 1.7.2 and Backbone.js.
Currently I have the following (which works)
MyView: Backbone.View.extend({
initialize: function() {
this.colorInput = $("<input />", {
"id": "color",
"name": "color",
"value": this.model.get("color")
});
var self = this;
this.colorInput.on("change", function() {
self.changeColor();
});
},
changeColor: function() {
var color = this.colorInput.val();
this.model.set("color", color);
}
});
I was trying to do it the other way where I just pass in my function.
this.colorInput.on("change", this.changeColor, this);
But when trying to do it that way, it throws the error
((jQuery.event.special[handleObj.origType] || {}).handle || handleObj.handler).apply is not a function
.apply( matched.elem, args );
(line 3332)
Which I'm not able to figure out. Any ideas why this way doesn't work?
Explicitly set this of the callback - part 1 bind [docs], which returns a new function with this bound to a value. The function has exactly the same behavior as the one you called . bind on, only that this was set by you. No matter how or when that function is called, this will always refer to the passed value.
Pro tip: When a function (callback) is invoked, the JavaScript interpreter creates an execution record (execution context), and this context contains information about the function. Amongst other things is the this reference, which is available for the duration of the function's execution.
You're confusing jQuery's on
:
.on( events [, selector] [, data], handler(eventObject) )
.on( events-map [, selector] [, data] )
with Backbone's on
:
object.on(event, callback, [context])
Backbone's takes a context as the third argument, jQuery's doesn't. Looks like jQuery's on
is interpreting your third argument as the handler(eventObject)
and trying to call it like a function, that would explain the error message that you're seeing.
Normally you'd do it more like this:
MyView: Backbone.View.extend({
events: {
'change input': 'changeColor'
},
initialize: function() {
this.colorInput = $("<input />", {
"id": "color",
"name": "color",
"value": this.model.get("color")
});
},
render: function() {
this.$el.append(this.colorInput);
return this;
},
changeColor: function() {
var color = this.colorInput.val();
this.model.set("color", color);
}
});
and let Backbone's event delegation system take care of things.
This is for the Googlers who come across this problem. I had this exact same issue and what occurred was that where the error was being reported and where the error actually occurred were in two different places.
One line of code was obsolete and looked something like
$('#modal').on('click', function(e) {
// Execute invalid code here.
});
The other line of code was similar:
$('#modal').on('click', function(e) {
// Execute valid code here.
});
The error was that the first invocation was not a true function, so the error was accurate, the second handler being invoked was not a true function and jQuery couldn't complete it, but it always acted as if it occurred on the second function call.
I'd say if you run into this error, remove any extra event handlers that may be triggered and see if that stops the problem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With