Reputation: 115
My ExtJS application displays certain UI elements depending on a boolean variable.
This boolean variable, however, is the result of calling an async function. As a result, the boolean is set to a Promise that is fulfilled, rather than true or false proper. This affects whether the UI elements are actually displayed (a Promise is not exactly a boolean, after all).
The code looks like this:
Ext.define('userDefinedComponent', {
extend: 'Ext.Container',
requires: ['someHelperFile'],
initComponent: function () {
var me = this,
var enabled = someHelperFile.someAsyncFunc() // enabled is a boolean that is returned as fulfilled Promise instead
Ext.apply(me, {
// layout and padding
items: [
{
xtype: 'internallyDefinedForm',
fieldConfigs: {
// other fields
'someFormField': {
hidden: !enabled, // depends on enabled
}
}
},
{
xtype: 'internallyDefinedGrid',
columnConfigs: {
// other columns
'someColumn': {
hidden: !enabled, // deends on enabled
}
},
}
]
})
}
})
I want the field enabled
to really be a boolean rather than a Promise. In other words, I want to wait for the someAsyncFunc
to run the result, before setting hidden
property of the internallyDefinedForm
and internallyDefinedGrid
.
What are my possibilities? I was thinking of using a beforerender
, like below:
Ext.define('userDefinedComponent', {
extend: 'Ext.Container',
requires: ['someHelperFile'],
initComponent: function () {
var me = this;
Ext.apply(me, {
// layout and padding
items: [
{
xtype: 'internallyDefinedForm',
fieldConfigs: {
// other fields
'someFormField': {
hidden: !me.enabled, // depends on enabled
}
}
},
{
xtype: 'internallyDefinedGrid',
columnConfigs: {
// other columns
'someColumn': {
hidden: !me.enabled, // deends on enabled
}
},
listeners: {
beforerender: function() { // this is the beforerender
me.enabled = someHelperFile.someAsyncFunc();
console.log("beforerender triggered in grid");
}
},
}
]
})
}
})
And in fact, using the beforerender
for the internallyDefinedGrid
only, I can see the text "beforerender triggered in grid" triggered very early. However, the fact remains that the behavior that I observe does not correspond to what I expect: although the async someAsyncFunc
should return true
based on the API response it gets, such that me.enabled
is true, the actual UI associated with the internallyDefinedGrid
behaves as if me.enabled
is false instead. I observe that the column on the UI is hidden, and this is only possible when me.enabled
is false, such that the column someColumn
does not appear on the grid. After all, the hidden
field of someColumn
is set to !enabled
.
I am confident that the UI for the grid behaves not like what I expect it to, so there is a problem with the async behavior. But I'm really lost as to how to set the asynchronously obtained enabled
or me.enabled
field adequately.
Any help is appreciated.
Upvotes: 0
Views: 532
Reputation: 9734
I would suggest to use a View Model and binding, as explained here.
Basically you define what your UI is depending on, under the data tag in the View Model (you can set the initial value here):
Ext.define('MyApp.TestViewModel', {
extend: 'Ext.app.ViewModel',
data: {
something: false,
},
}
Then you bind the visibility to this value in the view:
bind: {
hidden: '{something}'
}
or
bind: {
hidden: '{!something}'
}
You fetch the async data, and once you have the result, set the value in the View Model (this can be either the view or the controller):
this.getViewModel().set('something', RESULT_OF_ASYNC)
With binding ExtJS takes care of refreshing the visibility of your component every time when the value in the View Model is changed. There are good examples at the link I provided. This is a very powerful and complex feature of ExtJS, worth learning.
Upvotes: 1