PDA

View Full Version : Delay app init until Ext.direct API is loaded



LeonM
10 Oct 2012, 7:33 AM
I use Ext.direct to implement a third party API. The server configuration (list of exposed methods to the client) gets downloaded through AJAX, like this:



Ext.Ajax.request({
url: 'http://my.api.com/api/',
success: function (response, opts) {
var api_specs = Ext.decode(response.responseText);

Ext.direct.Manager.addProvider({
type: 'direct',
namespace: 'my_api',
url: 'http://my.api.com/api/',
actions: api_specs
});
}});


The problem here is that the API specification is loaded asynchronously, so whenever I try to use the API, like this:



xtype: 'form',
api: {
submit: 'my_api.user.login'
}


I get an error, because Ext tries to instantiate the form before the API method specification finishes loading.

So, I am looking for some way to 'delay' the instantiation of my app until the API is fully loaded. In Ext3 I would probably fire an event after the API loads and then nest a listener within Ext.onReady() or something like that, but I'm not sure how to do it in Ext4...

According to the docs, Ext.Application() gets launched "after the page is ready", so I guess that is the same as good old Ext.onReady()? So maybe I could somehow alter this behavior to launch it after the page is ready AND my API is loaded?

Or can I use the Ext.loader in some way perhaps?

LeonM
11 Oct 2012, 12:13 PM
Got it!


- Removed views and autoCreateViewport configs from Ext.application to make sure nothing gets loaded that depends on the API definition
- called api loader function from Ext.application.launch()
- added listener to event from the API loader after provider was added, which builds the viewport
- Ext.loader does the rest from there



Ext.direct.Manager.addProvider({
[...]
});
Ext.direct.Manager.fireEvent('api_load');




Ext.application({
name: 'MyApp',
controllers: ["api"],
launch: function(){
Ext.direct.Manager.on('api_load', function (){
Ext.create('MyApp.view.Viewport');
});
Ext.create('MyApp.controller.api');
}
});

LeonM
13 Oct 2012, 6:23 AM
My solution was not as good as I thought, I still ended up with classes instantiated before the API was fully loaded. I found a better way to do it.

- Removed all controllers from Ext.application(), except for the one responsible of loading the API
- Created all other controllers in the callback function of the API controller function after load.

Like this:


Ext.application({
name: 'MyApp',
controllers: ['api'],
autoCreateViewport: true
});


And the controller:



Ext.define('MyApp.controller.api', {
extend: 'Ext.app.Controller',
init: function () {
Ext.Ajax.request({
//Fetch the API descriptor
url: 'http://myapp/api/',
[...]
scope: this,
success: this.callBack,
});
},

callBack: function(response, opts){
[..process ajax response..]
this.getController('Workspace');
this.getController('Workspace').init();
this.getController('Login');
this.getController('Login').init();
}
})


I hope this might help someone else having a similar situation. Having to work through the weekend to meet a deadline is something I wouldn't wish on anyone ;)