
Nell'articolo precedente abbiamo parlato in generale dell'uso delle Promise
e della coppia async/await
. Purtroppo ExtJS il supporto è limitato alle chiamate AJAX. Sarebbe molto interessante poter utilizzare questo tipo di sintassi anche per le letture/scritture sugli store ma anche sui modelli o per ottenere il risultato da una dialogbox.
Store
Gli store
sono una delle classi più usate in ExtJS. Se l'unico scopo è visualizzare i dati da su una lista o una griglia non ci sono problemi, ma nel caso in cui si vogliano elaborare i dati una volta letti è necessarrio utlizzare una callback in questo modo:
store.load({ scope: this, callback: function(records, operation, success) { // the operation object // contains all of the details of the load operation console.log(records); }});
ExtJS fortunatamente ci dà la possibilità di modificare a piacimento anche classi esistenti tramite l'utilizzo di override
. Possiamo quindi modificare il metodo load
aggiungendo una configurazione, per esempio usePromise
, che trasformi il valore di ritorno di store.load
in una promise, in modo da poterla chiamare con await
.
Ext.define('Fiddle.overrides.Store', { override: 'Ext.data.ProxyStore', load(options) { let me = this; if (options && options.usePromise) { delete options.usePromise; return new Ext.Promise(function (resolve, reject) { me.load(Ext.apply(options || {}, { callback(records, operation, success) { if (success) { resolve(records); } else { reject(operation); } } })); }); } else { return this.callParent(arguments); } }});
In questo modo possiamo trasformare il codice precedente così:
const records = await store.load({ usePromise: true });console.log(records);
L'unica accortezza è che la funzione dove sarà inserito quel codice dovrà essere dichiarata come async
.
Dialog box
Con ExtJS anche il risultato di una semplice dialog box richiede una callback:
Ext.Msg.confirm('Info', 'Do you want to save changes?', function (buttonId) { if (buttonId === 'yes') { //... }});
In questo caso probabilmente invece che usare un override ha più senso creare una nuova classe singleton
:
Ext.define('Fiddle.Message', { singleton: true, confirm(message) { var me = this; return new Ext.Promise(function (resolve, reject) { Ext.Msg.confirm(document.title, message, function(buttonId) { resolve(buttonId); }); }); }});
Notate che non è stato necessario usare il metodo reject
della promise in quanto la dialog box non ha una condizione di errore.
In questo modo il codice precedente diventa questo:
const buttonId = await Fiddle.Message.confirm('Do you want to save changes?');if (buttonId === 'yes') { //...}
Conclusione
Usando una struttura simile si può aggiungere il supporto alle promise e async/await dovunque sia necessario rendendo il codice sicuramente più leggibile.
Potete provare gli esempi dell'articolo su questo fiddle.