The Sencha Ext JS framework has become the industry standard for developing enterprise web applications thanks to its comprehensive widget library, powerful data package and robust tooling. Since the original Ext JS 1.0 release in 2007, a lot has changed in our industry — and web applications are certainly larger and more complicated than ever.
Because application architecture is as much about providing structure and consistency as it is about actual classes and framework code, building a good architecture unlocks a number of important benefits:
- Every application works the same way, so you only have to learn it once
- It’s easy to share code between apps, because they all work the same way
- You can use build tools to create optimized versions of your applications for testing and production use
While Touch 1.0 and Ext JS 4.0 defined some best practices on how to structure your application using MVC, Ext JS 5 takes this concept to the next level by adding optional support for the MVVM architectural pattern. Although MVC and MVVM are in fact very similar software patterns, using MVVM has some specific benefits that can vastly reduce the amount of application logic developers need to write.
It is important to note that Ext JS 5 maintains full backwards compatibility with applications built with an MVC architecture. To help you understand what has and hasn’t changed, let’s take a deeper look at what the MVC and MVVM patterns do.
What is MVC?
Model-View-Controller (MVC) is an architectural pattern for writing software. It divides the user interface of an application into three distinct parts, helping to organize the codebase into logical representations of information depending upon their function.
MVC implementations may vary slightly between applications, but generally speaking each part of the architecture has specific responsibilities:
- The Model describes a common format for the data being used in the application. It may also contain business rules, validation logic, and various other functions.
- The View represents the data to the user. Multiple views may display the same data in different ways (e.g. charts versus grids).
- The Controller is the central piece of an MVC application. It listens for events in the application and delegates commands between the Model and the View.
MVC: An Example
Let’s take a look at an example in Sencha Fiddle:
In this example, we see a simple MVC application involving a Master / Detail layout. The master view (an Ext.grid.Panel) contains records which, when selected, populate a related detail view (an Ext.form.Panel). Clicking the “Save” button (on the detail view) updates the record in the master view.
While this is a relatively simple example, you will notice that there is a lot of manual work in the controllers to manage component and model references — specifically for the detail view.
We will come back to this example in a moment to explore an alternate architecture.
What is MVVM?
Model-View-ViewModel (MVVM) is another architectural pattern for writing software that is largely based on the MVC pattern. The key difference between MVC and MVVM is that MVVM features an abstraction of a View (the ViewModel) which manages the changes between a Model’s data and the View‘s representation of that data (i.e. data bindings) — something which typically is cumbersome to manage in traditional MVC applications.
The MVVM pattern attempts to leverage the architectural benefits of MVC (separation of functional responsibilities) yet also provides the additional advantages of data binding. The result is that the Model and framework perform as much work as possible, minimizing (and in some cases eliminating) application logic that directly manipulates the View.
Elements of the MVVM pattern include:
- The Model describes a common format for the data being used in the application, just as in the classic MVC pattern.
- The View represents the data to the user, just as in the classic MVC pattern.
- The ViewModel is an abstraction of the view that mediates changes between the View and an associated Model. In the MVC pattern, this would have been the responsibility of a specialized Controller, but in MVVM, the ViewModel directly manages the data bindings and formulas used by the View in question.
Keep in mind that not all Views in MVVM require a ViewModel, but when they are used, ViewModels are created for each related View, meaning that multiple instances might live simultaneously.
MVVM: An Example
Revisiting the previous example built with MVC, it seems that MVVM might solve some of the problems we had manually managing component and model references through data binding. In a revised example, built with Ext JS 5, we have replaced the Detail controller with a ViewModel to manage the data binding between the record and the two views sharing the record’s data.
We no longer need to click “Save”, and the record’s data is instantly updated everywhere thanks to two-way data binding. This saves us a lot of manual work and ultimately simplifies how large applications manage data.
What happened to Controllers in MVVM?
Despite the name Model-View-ViewModel, the MVVM pattern may still utilize Controllers — although one might choose to then call it an MVC+VM architecture. Confusing acronyms aside, the point here is that Ext JS 5 does not force you to choose between MVC and MVVM (see a hybrid example here).
Ext JS 4 introduced MVC Controllers in a global sense, and Ext JS 5 still supports that concept. However, Ext JS 5 also supports a new variation termed ViewController.
A ViewController is similar in nature to a ViewModel. Both constructs are scoped directly to the related View, eliminating much of the overhead required in traditional MVC to manage object references and restore application state.
ViewControllers are also similar to traditional (i.e. global) MVC Controllers from Ext JS 4 in that they listen for events and execute logic in response to those events. However, a major difference between ViewControllers and traditional Controllers is that individual ViewControllers are created for each related View, whereas Controllers are singular constructs listening globally across multiple Views.
ViewControllers and ViewModels participate in the Component lifecycle — meaning that for every instance of a View, unique instances of the configured ViewModel and ViewController are also created. The ViewModel and ViewController are subsequently destroyed when their associated View is destroyed.
On the one hand, this is great news because the application can (in theory) save memory and processing time by avoiding a more generic Controller, which would listen globally for events on Views that may not even exist. But on the other hand, it’s possible that memory use could grow due to multiple ViewModel and ViewController instances living simultaneously.
Lastly, keep in mind that not all Views in MVVM require a ViewController — they are completely optional.
Ext JS 4 paved the way for enterprise web applications to begin using MVC, defining a consistent architecture for organized code. Ext JS 5 has added support for MVVM while maintaining backwards compatibility for MVC, so developers should have no problems upgrading all apps built using Ext JS 4 to the latest version.
The best practices surrounding MVC architecture are still relevant in Ext JS 5, yet developers can now vastly reduce the amount of application logic necessary to build large and complex apps through two-way data binding.
This article is the first in a series surrounding the idea of application architecture, MVVM and data binding. Look for upcoming, detailed posts on ViewControllers and declarative listeners.