Event-Driven UI Example
An event-driven interface lets components talk to each other without holding direct references, by publishing events to a shared bus that others subscribe to. This example builds a search box, a results list, and a counter that coordinate entirely through events, so none of them knows the others exist. It uses Backbone.Events as the bus.
For the architecture, see event-driven user interfaces and component communication.
What you'll learn
What this example builds
The example connects three independent components through a single event bus: a search box that announces queries, a list that shows results, and a counter that tracks how many searches happened.
The behaviour you will see
Typing in the search box publishes a search event. The results list and the counter both react to it, yet the search box references neither of them. New components can listen to the same event without any existing code changing, which is the point of an event-driven design.
Creating the event bus
A bus is any object mixed with Backbone.Events, giving it trigger and on.
The shared channel
var bus = _.extend({}, Backbone.Events);
Publishing events
A component announces that something happened by triggering an event, with no idea who is listening.
The search box publishes
$("#search").on("input", function () {
bus.trigger("search", this.value);
});
Subscribing to events
Other components listen for events they care about and react in their own way.
Two independent listeners
bus.on("search", function (query) {
$("#results").text("Results for: " + query);
});
var count = 0;
bus.on("search", function () {
count += 1;
$("#count").text(count + " searches");
});
Each listener handles the same event differently, and adding a third changes nothing about the first two, a property explored in component communication.
Why decoupling helps
The value of the bus is what it removes: direct connections between components.
Components that do not know each other
Because the search box only triggers an event, it has no reference to the list or the counter, and they have no reference to it. Any component can be added, removed, or replaced without touching the others, as long as the events stay the same. This keeps a growing interface from turning into a web of direct calls where every change risks breaking something unrelated, which is the failure mode event-driven UI prevents.
Common pitfalls
Event-driven code has its own traps.
What usually goes wrong
The most common is never unsubscribing, so removed components keep reacting to events and leak. Use listenTo and stopListening for components with a lifecycle. The second is inventing too many event names with unclear meanings, which makes the flow hard to follow; keep names few and descriptive. The third is using events for direct request and response where a plain function call would be clearer. The broader pattern is in event-driven user interfaces.
Frequently Asked Questions
What is an event bus in JavaScript?
An event bus is a shared object that components publish events to and subscribe to, letting them communicate without direct references. In this example it is created by mixing Backbone.Events into a plain object.
How does event-driven UI decouple components?
Components only trigger and listen to events, never each other. A publisher has no reference to its listeners, so any component can be added, removed, or replaced without changing the others, as long as the events stay the same.
How do I avoid leaks in event-driven code?
Use listenTo and stopListening for components that have a lifecycle, so they stop reacting to events when removed. Listeners left attached after a component is gone keep firing and leak memory.
When should I not use events?
Avoid events for direct request and response where a plain function call is clearer, and avoid inventing many vague event names. Events are best for broadcasting that something happened to unknown listeners.
Read next: the rendering example, or back to the Examples hub.
Want the architecture behind it?
The event-driven UI guide covers buses, decoupling, and component communication.
Read: Event-Driven UI →