ExtJS 6: Getting your Controllers to talk to one another.

Bryan P Johnson
Jul 9, 2015 · 4 min read

Like most new versions of a programming library, version 6 of ExtJS has brought with it a number of changes for users coming from Sencha Touch. Perhaps the biggest of these changes is the switch from an MVC (Model — View — Controller) architecture to an MVVM (Model — View — ViewModel) architecture.

In the old MVC world, a set of common views would be grouped under a single controller. This allowed for easy communications between these shared views using the common controller. However, in the switch over to an MVVM architecture, each view has its own separate controller, as well as its own ViewModel, which governs the data for an individual view.

This separation is great for creating discrete chunks of self-contained code that can be reused in multiple applications. For anyone who has created and recreated code for system users (login, profiles, lists of users, etc.), this can be a godsend. If each View — Controller — ViewModel is a self-contained piece, it’s trivial to copy the code to a new application.

But every so often, you need to have your views talk to each other. Maybe you edited a user in the User Profile view and you need to notify your main view so it can update the user’s avatar. We could, within the User Profile’s ViewController, use an Ext.ComponentQuery to find the main view and update it, but that means that if we ever updated our main view, we’d have to remember to fix our User Profile ViewController as well.

In the MVC world we could have one controller that was responsible for listening to the User Profile for changes, then updating the appropriate components elsewhere in the application, and that’s definitely one solution for your MVVM application as well: create an application-level controller to listen for cross-view events. But what if the view you need to listen to, or that you need to modify, hasn’t been created yet? Your app controller needs to be aware of what’s there and what isn’t.

Meet the Mediator Object

A third, and potentially better option, is to use a Mediator object. A Mediator is essentially a third party whose sole purpose is to pass events around between objects that emit them and objects that need to listen for them. An object that uses the Observable mixin works great for this:

Now you just require this in your view controllers and either fire events or listen for them:

Since the Mediator object always exists, you can add listeners or fire events at any time, and only ViewControllers that are currently active will be affected.

Now when our UserProfileViewController’s onUserUpdated function is called, we notify the Mediator object that we’ve done a user update. Any other Controllers that are listening for that event get sent the updated user data. And our User Profile view doesn’t need any knowledge of what they are or what they’re doing with the data.

A step further

I’m a big fan of removing as much boilerplate code as possible. So even though the Ext.ux.Mediator object is a good solution to our problem, we can go one better. Why not make it a mixin and have it read configurations from our controllers, rather than having to write code into each controller for sending and receiving these events?

My code for the Mediator mixin is up on GitHub, but here’s an example of how to modify the previous two controllers to use it:

You see that we have three files now. The first is called “AbstractController” and just includes the mixin. That way, if I always extend my AbstractController rather than Ext.app.ViewController, I know that I’ll always have the right set of mixins for all of my ViewControllers.

In the MainViewController we’ve removed the init function and added a “subscribe” config. Now when the mediator fires the “userupdate” event, our main controller will call its updateUserAvatar function.

In our UserProfileViewController, we now call “this.publish” rather than the much longer Ext.ux.Mediator.fireEvent. This is a handy shorthand function added by the Mediator mixin that works exactly the same as fireEvent.

So you can see from these examples that communication between separate ViewControllers can be easily established without traveling too far outside the “Official Sencha Way of Doing Things.”

By combining a Mediator object and an abstract controller, you can quickly add communication between your controllers. After that, it’s just a simple matter of publish and subscribe to get the different view controllers talking.

Now you can get back to coding the next big thing.

Twelve Foot Guru

Code Monkeys Effing the Ineffable

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store