Listen For Changes Against An Object In An Array Without Nesting Event Listeners
Solution 1:
You could just check if the save
event is already binded, in that case not bind it again, like this:
// if no 'save' event already bindedif (!$(user).data('events') || !$(user).data('events').save) {
// listen for the save event
$(user).on("save", function(){
// Alert the view
});
}
See working example
To put some sugar on top, we can make the "check if event exist" logic into a custom jquery pseudo-selector, that would be defined as follows:
$.expr[':'].hasEvent = function(obj, idx, meta, stack) {
return ($(obj).data('events') != undefined
&& $(obj).data('events')[meta[3]] != undefined);
};
Then you can use it this way:
$(user).not(":hasEvent(save)").on("save", function(){
// Alert the view
});
Working example
UPDATE FOR JQUERY >= 1.8
Starting with jQuery 1.8 there were some changes to the events object which makes my above code not to work, see this excerpt from the jQuery 1.8 release notes:
$(element).data(“events”): In version 1.6, jQuery separated its internal data from the user’s data to prevent name collisions. However, some people were using the internal undocumented “events” data structure so we made it possible to still retrieve that via
.data()
. This is now removed in 1.8, but you can still get to the events data for debugging purposes via$._data(element, "events")
. Note that this is not a supported public interface; the actual data structures may change incompatibly from version to version.
So here I post the jQuery >= 1.8 updated versions for of my above examples:
Checking if the save event is already binded, in that case not bind it again:
// if no 'save' event already bindedif (!$._data(user, 'events') || !$._data(user, 'events').save) {
// listen for the save event
$(user).on("save", function(){
// Alert the view
});
}
And the custom jquery pseudo-selector:
$.expr[':'].hasEvent = function(obj, idx, meta, stack) {
return ($._data(obj, 'events') != undefined
&& $._data(obj, 'events')[meta[3]] != undefined);
};
Solution 2:
I agree that the nested listener is a little weird--after all, you're already in a save listener, just for the button click rather than the model object.
I think I'd rewrite the code something like this:
$("#user-devices").on("click", ".device button", function(){
var button = $(this),
deviceId = $(this).closest(".device").attr("data-id"),
device = userDevices.get(deviceId);
if (device.get("Active") === "1")
{
$("#reactivation-warning-dialog").modal("show");
$("#reactivation-warning-dialog .btn-primary").on("click", device.activate);
}
else
{
device.activate();
}
});
//in the device "class"
{
...
...
activate: function() {
//persist and stuf.//on success...this.render();
}
render: function() {
button.removeClass("btn-danger").addClass("btn-success");
$("#activation-dialog").modal("show");
}
}
Post a Comment for "Listen For Changes Against An Object In An Array Without Nesting Event Listeners"