In the previous article we explored what it would mean to architect a Pandora-style application inside of Ext JS. We took a look at starting with the Model-View-Controller architecture and how to apply it to a relatively complex UI applications that had multiple views and multiple models. In this article we're going to explore how to move beyond just architecting it visually, and how to design and code the controllers and the models, and how it all wires up, starting with Ext.application and the Viewport class. Let's actually jump in and start writing the application. ## Defining our application In Ext 3, the entry point into your application was the Ext.onReady method, leaving it up to the developer to come up with an application architecture. In Ext 4 we have an introduced an MVC-like pattern. Using this helps you follow best practices when creating your applications. The entry point into an application written using the new MVC package will require you to use the ***Ext.application*** method. This method will create an ***Ext.app.Application*** instance for you and will fire the ***launch*** method as soon as the page is ready. This essentially replaced the need to use ***Ext.onReady*** while adding new functionality like automatically creating a viewport and setting up your namespace. ***app/Application.js*** Ext.application({ name: 'Panda', autoCreateViewport: true, launch: function() { // This is fired as soon as the page is ready } }); The *name* configuration causes a new namespace to be created. All our views, models, stores and controllers will live in this namespace. By setting *autoCreateViewport* to true, the framework will by convention include the **app/view/Viewport.js** file. In this file a class should be defined with the name **Panda.view.Viewport**, matching the namespace that was specified by the ***name*** configuration on your application. ## The Viewport class When we looked at what views were needed for our UI we were very focused on the individual parts. The Viewport of an application acts as the glue for these individual parts. It loads the required views and defines the configuration needed to achieve your app's overall layout. We have found that progressively defining our views and adding them to the viewport is the fastest way to create the base structure of your UI. It is important during this process to focus on scaffolding your views and not on the individual views themselves. Its almost like sculpting. We start by creating the very rough shapes of our views, and add more detail to them later. ## Creating the building blocks Leveraging the preparations we already did in the previous article, we are able to define many of the views at once.  ***app/view/NewStation.js*** Ext.define('Panda.view.NewStation', { extend: 'Ext.form.field.ComboBox', alias: 'widget.newstation', store: 'SearchResults', ... more configuration ... }); ***app/view/SongControls.js*** Ext.define('Panda.view.SongControls', { extend: 'Ext.Container', alias: 'widget.songcontrols', ... more configuration ... }); ***app/view/StationsList*** Ext.define('Panda.view.StationsList', { extend: 'Ext.grid.Panel', alias: 'widget.stationslist', store: 'Stations', ... more configuration ... }); ***app/view/RecentlyPlayedScroller.js*** Ext.define('Panda.view.RecentlyPlayedScroller', { extend: 'Ext.view.View', alias: 'widget.recentlyplayedscroller', itemTpl: '
{description}
', ... more configuration ... }); We have left out some of the configuration here since component configurations are not in the scope of this article.  In the above configurations you'll notice that we have three stores configured. These map to the store names prepared in the previous article. At this point we'll need to go ahead and create our stores. ## The models and stores Often it is useful to start with static json files containing mock data to act as our server side. Later we can use these static files as a reference when actually implementing a dynamic server side. For our app we had decided to use two models, Station and Song. We also need three stores using these two models that will be bound to our data components. Each store will load its data from the server-side. The mock data files would look something like the following. ### Static data ***data/songs.json*** { 'success': true, 'results': [ { 'name': 'Blues At Sunrise (Live)', 'artist': 'Stevie Ray Vaughan', 'album': 'Blues At Sunrise', 'description': 'Description for Stevie', 'played_date': '1', 'station': 1 }, ... ] } ***data/stations.json*** { 'success': true, 'results': [ {'id': 1, 'played_date': 4, 'name': 'Led Zeppelin'}, {'id': 2, 'played_date': 3, 'name': 'The Rolling Stones'}, {'id': 3, 'played_date': 2, 'name': 'Daft Punk'} ] } ***data/searchresults.json*** { 'success': true, 'results': [ {'id': 1, 'name': 'Led Zeppelin'}, {'id': 2, 'name': 'The Rolling Stones'}, {'id': 3, 'name': 'Daft Punk'}, {'id': 4, 'name': 'John Mayer'}, {'id': 5, 'name': 'Pete Philly & Perquisite'}, {'id': 6, 'name': 'Black Star'}, {'id': 7, 'name': 'Macy Gray'} ] } ### Models Models in Ext 4 are very similar to Records we had in Ext 3. One key difference is that you can now specify a proxy on your model, as well as validations and associations. The Song model for our application in Ext 4 would look like this. ***app/model/Song.js*** Ext.define('Panda.model.Song', { extend: 'Ext.data.Model', fields: ['id', 'name', 'artist', 'album', 'played_date', 'station'], proxy: { type: 'ajax', url: 'data/recentsongs.json', reader: { type: 'json', root: 'results' } } }); As you can see we have defined the proxy on our model. It is generally good practice to do this as it allows you to load and save instances of this model without needing a store. Also, when multiple stores use this same model, we don't have to redefine our proxy on each one of them. Lets go ahead and also define our Station model. ***app/model/Station.js*** Ext.define('Panda.model.Station', { extend: 'Ext.data.Model', fields: ['id', 'name', 'played_date'], proxy: { type: 'ajax', url: 'data/stations.json', reader: { type: 'json', root: 'results' } } }); ### Stores In Ext 4, multiple stores can use the same data model, even if the stores will load their data from different sources. In our example, the Station model will be used by both the SearchResults and the Stations store, both loading the data from a different location. One returns search results, the other returns the user's favorite stations. To achieve this, one of our stores will need to override the proxy defined on the model. ***app/store/SearchResults.js*** Ext.define('Panda.store.SearchResults', { extend: 'Ext.data.Store', requires: 'Panda.model.Station', model: 'Panda.model.Station', // Overriding the model's default proxy proxy: { type: 'ajax', url: 'data/searchresults.json', reader: { type: 'json', root: 'results' } } }); ***app/store/Stations.js*** Ext.define('Panda.store.Stations', { extend: 'Ext.data.Store', requires: 'Panda.model.Station', model: 'Panda.model.Station' }); In the ***SearchResults*** store definition we have overridden the proxy defined on the ***Station*** model by providing a different proxy configuration. The store's proxy used when calling the store's *load* method instead of the proxy defined on the model itself. Note that you could implement your server-side to have one API for retrieving both search results and the user's favorite stations in which case both stores could use the default proxy defined on the model, only passing different parameters to the request when loading the stores. Lastly let's create the RecentSongs store. ***app/store/RecentSongs.js*** Ext.define('Panda.store.RecentSongs', { extend: 'Ext.data.Store', model: 'Panda.model.Song', // Make sure to require your model if you are // not using Ext 4.0.5 requires: 'Panda.model.Song' }); Note that in the current version of Ext the 'model' property on a store doesn't automatically create a dependency, which is why we have to specify *requires* in order to be able to dynamically load the model. Lastly, for convention, we always try to pluralize the store names, while keeping the model names singular. ### Adding the stores and models to our application Now that we have defined our models and stores, its time to add them to our application. Let's revisit our Application.js file. ***app/Application.js*** Ext.application({ ... models: ['Station', 'Song'], stores: ['Stations', 'RecentSongs', 'SearchResults'] ... }); Another advantage of using the new Ext 4 MVC package is that the Application will automatically load the stores and models defined in the ***stores*** and ***models*** configurations. Then it will create an instance for each store loaded, giving it a storeId equal to its name. This allows us to use the name of the store whenever we bind it to a data component like we did in our views, e.g. store: 'SearchResults'. ## Applying the glue Now that we have our views, models and stores, it's time to glue them together. You start by adding the views one by one to your viewport. This will make it easier to debug any wrong view configurations. Let's go through the resulting viewport for the Panda app. Ext.define('Panda.view.Viewport', { extend: 'Ext.container.Viewport', Your Viewport class will usually want to extend *Ext.container.Viewport*. This will cause your app to take up all the available space in your browser window. requires: [ 'Panda.view.NewStation', 'Panda.view.SongControls', 'Panda.view.StationsList', 'Panda.view.RecentlyPlayedScroller', 'Panda.view.SongInfo' ], We set up all the view dependencies in our viewport. This will allow us to use their xtypes, previously configured in our views using the ***alias*** property. layout: 'fit', initComponent: function() { this.items = { xtype: 'panel', dockedItems: [{ dock: 'top', xtype: 'toolbar', height: 80, items: [{ xtype: 'newstation', width: 150 }, { xtype: 'songcontrols', height: 70, flex: 1 }, { xtype: 'component', html: 'Panda