Ext JS 4: Loading Reference Data Prior to Starting Application

I have recently found that I either need to load reference data or meta data to support role-based navigation before building the viewport.

In the first example below, I’m populating a variety of data stores prior to actually loading my application. This example does not use the MVC pattern.

In the second example, I’m loading toolbar configurations and other meta-data such as titles that are role-based before loading my application.

Loading Reference Data – Example 1

Ext.define('MyApp', {

	requires: [
		'Ext.Viewport',
	],

    launch: function() {

		this.storeOne = Ext.create('Ext.data.Store', {
			storeId: 'storeOne',
			model: 'MyApp.MyModel',
			autoLoad: false
		});
		
		this.storeTwo = Ext.create('Ext.data.Store', {
			storeId: 'storeTwo',
			model: 'MyApp.AnotherModel',
			autoLoad: false
		});
		
		Ext.Ajax.request({
			url: './url/for/refdata',
			jsonData: storeList,
			scope: this,
			success: this.onRefDataLoaded,
			failure: this.onRefDataLoadError
		});
	},

	onRefDataLoaded : function (response) {
		var json = Ext.decode(response.responseText), msg, item,
			success = false;

		if (typeof json.success !== "undefined" && json.success === false) {
			msg = json.message;
		} else {
			try {
				this.storeOne.loadRawData(json.storeOneData);
				this.storeTwo.loadRawData(json.storeTwoData);
				success = true;
			} catch (err) {
				msg = "An unexpected error occurred.";
			}
		}

		if (success) {
			item = {
				// put the application config stuff here.
				// i have a panel with a form on it
			};
		} else {
			// build a panel that will show the error message
			item = {
				xtype: 'panel',
				autoScroll: true,
				html: msg,
				bodyPadding: 10
			};
		}

		this.mainView = Ext.create('Ext.container.Viewport', {
            layout: 'border',
            items : [
				{
					id: 'center-container',
					xtype: 'container',
					region: 'center',
					layout: 'fit',
					items: [item]
				}
			]
		});
	},

	// Couldn't properly load the reference data, the AJAX request failed
	// Build the viewport with the error message
	onRefDataLoadError : function () {
		this.mainView = Ext.create('Ext.container.Viewport', {
			layout: 'border',
			items : [
				{
					id: 'center-container',
					xtype: 'container',
					region: 'center',
					layout: 'fit',
					items: {
						xtype: 'panel',
						autoScroll: true,
						html: "Something went wrong",
						bodyPadding: 10
					}
				}
			]
		});
	}
});

The JSON response for the ref data load looks like this:

{
	"storeOneData" : {
		"success" : true,"rows" : [
			{"id":1, "type":"UserType1"},
			{"id":2, "type":"UserType2"}
		]
	},
	"storeTwoData" : {
		"success" : true,"rows" : [
			{"id":1, "genre":"Jazz"},
			{"id":2, "genre":"Rock"},
	        {"id":3, "genre":"Pop"},
	        {"id":4, "genre":"Hip Hop"}
		]
	},
}

Loading Navigation Configurations – Example 2
In this example, instead of populating data stores, I’m querying the server to get configs for a toolbar and other data for the specific user. This example is using the MVC pattern, but dynamically loading the the controllers, following the pattern described here: An ExtJS MVC application with dynamically loaded views and controllers. The interesting part are the launch and onLoadNavButtons methods.

Ext.application({
	autoCreateViewport: false,
	name: 'MyApp',

	requires: [
	],

	appFolder: 'myapp/app',

	launch : function () {
		// Load the app navigation buttons
		Ext.Ajax.request({
			url: './url/to/get/refdata',
			scope:this,
			success:this.onLoadNavButtons,
			failure:function () {
				Ext.msg.alert("My App Initialization Failed", "Initial Loading Error");
			}
		});
	},

	onLoadNavButtons : function(xhr) {
		var viewPortData = Ext.decode(xhr.responseText),
			i, tot;
		this.navButtons = viewPortData.navButtons;
		this.defaultAction = viewPortData.defaultAction;
		this.viewportMetaData = viewPortData.viewportMetaData;
		this.buildViewPort();
	},

	buildViewPort : function () {
		this.viewport = Ext.create( "MyApp.view.Viewport", {
			viewportMetaData : this.viewportMetaData,
			navButtons: this.navButtons
		});
		var c = this.getController('Viewport'),
			da = this.defaultAction;
		c.init();
		this.runAction(da.controllerName, da.actionName, da.extra);
	},

	runAction : function (controllerName, actionName) {
		Ext.log(controllerName + ' ' + actionName);
		var controller = this.getController(controllerName),
			viewPort = this.getController('Viewport');
		controller.init(this);
		controller['action'+actionName].apply(
		    controller, Array.prototype.slice.call(arguments, 2));
		viewPort.toggleButtons.apply(viewPort,Array.prototype.slice.call(arguments, 2));
	},

	setMainView: function(view) {
		var center =  this.viewport.layout.centerRegion;
		if(center.items.indexOf(view)===-1){
			center.add(view);
        	}
		center.getLayout().setActiveItem(view);
	}
});

And the JSON that is returned from the server is

{
	"viewportMetaData" : {
		"title" : "My App Title Here",
		"hideToolbar" : false
	},
	"defaultAction" : {
		"controllerName" : "Home",
		"actionName" : "Show",
		"extra": "homeBtn"
	},
	"navButtons":[
		{
			"text": "Home",
			"itemId": "homeBtn",
			"iconCls": "icon-house"
		},
		"-",
		{
			"text":"Another Button",
			"itemId":"anotherBtn",
			"iconCls":"icon-door-in"
		},
		"-",
		{
			"text":"One More Button",
			"itemId":"moreButton",
			"iconCls":"icon-arrow-redo"
		}
	]
}

And then, in my Viewport “view” I use the navigation button configs when building the toolbar for the viewport.

Helpful Links:

Version Info: Ext JS 4.1.1

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s