views:

73

answers:

3

I've been reading about custom events in jQuery and why they should be used but I'm still clearly missing the point. There is a very good article I read here that has the following code example;

function UpdateOutput() {
    var name = $('#txtName').val();
    var address = $('#txtAddress').val();
    var city = $('#txtCity').val();

    $('#output').html(name + ' ' + address + ' ' + city);
}

$(document).bind('NAME_CHANGE ADDRESS_CHANGE CITY_CHANGE', function() {
    UpdateOutput();
});

$('#txtAddress').keyup(function() {
    $(document).trigger('ADDRESS_CHANGE');
});
$('#txtCity').keyup(function() {
    $(document).trigger('CITY_CHANGE');
});

Can someone tell me why I just don't call the UpdateOutput() function directly? It would still work exactly the same way, i.e.

$('#txtAddress').keyup(function() {
    UpdateOutput()
});
$('#txtCity').keyup(function() {
    UpdateOutput()
});

Many thanks

+2  A: 

As your article starts with:

As everyone knows, the more dependencies you have in a system, the harder maintaining that system is. Javascript is no exception- and orchestrating actions across complex user interfaces can be a nightmare if not done properly.

Using events removes (some of) these dependencies:

  • When something happens (a key is released/up), a notification of this event is send, without knowing whether anyone is interested at the moment or not.
  • When someone is interested in a certain event he can subscribe for it, without knowing why this event was triggered (key released)

Both bullets are independent, the first notifies and the second responds. Removing one does not matter for the functionality of the other. It is also easy to have multiple instances firing/subscribing to events (Also due to the missing dependencies).

Veger
So what you're saying is that if I was to trigger an event and no function had been bound to the event then there would be no error i.e. $(document).trigger('ADDRESS_CHANGE') but if I was calling the function directly then it would result in an error?
Nick Lowman
Yes, except that you only would get an error by direct calling if that function is not defined of course. And I suppose that multiple functions could be bound to a single event (and vice versa) and all being triggered, when the event is fired.
Veger
Thanks for your help Veger. I'm slowly beginning to understand the benefits but it would help if I had a UI rich project to work on.
Nick Lowman
A: 

Because you are one client of that event, even though you have full control over the entire application. It helps decoupling your code better.

As one of the clients who is interested in knowing when the name, address, or city changes, you are updating the values in some part of the screen. Some other client might want to do something else such as pull up all adjacent cities, reverse geocode the address, do a name lookup on namesdatabase.com, and so on.

You can still control everything without events and call multiple functions directly or put everything in it's own function, but adding events decouples the implementation from what needs to be done, based only on the type of event, so UpdateOutput does not have to worry about pulling up names from a names database, and you don't have to worry about calling all the necessary functions yourself whenever a particular event happens as long as there is a basic understanding of the events defined in the system and what they represent.

A second reason is abstraction. For example, deleting of a user account might get triggered by a simple click, but just by translating that to a higher level event such as DeleteAccount, things would get simpler and understandable when you consider that there could be tens, or hundreds, or maybe even thousands of such events all across the application. Working at a higher level of abstraction than "keyups", "keydowns", "mouseovers", etc. (which are really meaningless anyways in the context of an application and the intent behind), things can get a lot more manageable as the application size grows.

Anurag
@Anurag - Thanks for the response, which I've re-read maybe 5 times now and still can't see why calling a function directly i.e. deleteAccount() and calling it via an event i.e. $(document).trigger('DELETE_ACCOUNT') which then calls deleteAccount() makes any difference to my code. deleteAccount() still gets called either way? I've been reading a lot of articles on this now and hopefully the penny will drop as it's driving me mad that I can't see the benefits.
Nick Lowman
I think a better way to understand this would be to write a small application that's very rich on the UI, and then see how involved things can get. In the above example, you would have a mapping from `click -> function 1, function 2, ..`, and have lots of these, if you rely directly on the DOM event. With custom events, you'd have one level of abstraction such as `AccountDeleted -> function 1, function 2, ..`. Nothing changes in terms of what actually gets done, but it's just a more manageable approach.
Anurag
Thanks for your help Anurag.
Nick Lowman
You're welcome @Nick. Glad I could convince you in favor of custom events :)
Anurag
A: 

It’s perfectly reasonable to wire up the UpdateOutput() call directly. Often, it’s difficult to represent the need for an abstraction that custom event pooling provides in simple examples.

However, there’s (arguably) two issues of maintainability (again, depending on the use) when calling UpdateOutput directly. The first problem occurs by repeating the UpdateOutput() call in numerous places. This makes refactoring functions (especially those with parameters) extremely difficult when they change. With Event Pooling, you can prep data before passing it to a function, which is helpful when disparate code blocks call the same function. With ajax heavy web apps around, controlling function calls is very important.

Secondly, it’s possible you’ll need to call multiple functions for the same event. Imagine in addition to UpdateOutput(), there’s also some validation function which needs to be fired. Or when a user updates the zip code, some maps api is trigged to show something, or whatever other functionality which could happen (the point being you may have numerous functions being called in a simple keyup() event. Having this wired up directly makes for very large blocks of code which simply call multiple functions, and if there’s conditional logic required, they can get out of hand. Rewritten with event pooling, you get a lot more control of how a function like UpdateOuput is being called, so you don’t need to chase down the method across numerous files. You can simply see what events that cal is binded too.

mhamrah
Thanks mhamrah.
Nick Lowman