Una delle principali limitazioni che ho trovato nella gestione dei Record in ExtJS è la mancanza di una qualsivoglia struttura per gestire l'associazione tra differenti Record. Qualsiasi applicazione, pur piccola, presenta un modello di dati con entità tra di loro relazionate. Si hanno infatti oggetti che incapsulano tra i loro attributi altri oggetti sia in formato scalare (oggetto singolo) che in formato vettoriale (lista di oggetti). ExtJS nella definizione di un particolare Record non presenta questa possibilità. Le uniche tipologie di attributo sono “piatte” come per esempio stringhe, numeri o date. L'unico sistema per incapsulare in maniera impropria un entità all'interno di un record era quella di non definire la tipologia di dato in modo che il motore di ExtJS non convertisse l'oggetto in nessun modo mantenendo quindi la struttura originale. Facciamo un esempio:
Ipotizziamo che il server invii al client un oggetto JSON di questo tipo:
{ "firstname": "AAA", "lastname": "BBB", "age": "30", "car": { "manufacturer": "Mercedes", "model": "SLK" } }
Per rappresentare all'interno di un Record i dati ricevuti possiamo procedere con due modi differenti:
var Persona = Ext.data.Record.create({ { name: 'firstname', type: 'string' }, { name: 'lastname', type: 'string' }, { name: 'age', type: 'int' }, { name: 'car_manufacturer', type: 'string', mapping: 'car.manufacturer' }, { name: 'car_model', type: 'string', mapping: 'car.model' } });
var Persona = Ext.data.Record.create({ { name: 'firstname', type: 'string' }, { name: 'lastname', type: 'string' }, { name: 'age', type: 'int' }, { name: 'car' } });Entrambi gli approcci presentano però notevoli problemi:
Ipotizzando di avere la variabile persona popolata con i dati visti in precedenza possiamo scrivere:
var persona = ... //ottengo il Record da un apposito Reader persona.get("car_manufacturer") //ritornerà "BMW" persona.get("car_model") //ritornerà "SLK"
var persona = ... //ottengo il Record da un apposito Reader var carJson = persona.get("car") car.manufacturer //ritornerà "BMW" car.model //ritornerà "SLK"
Ext.ux.data.XRecord permette proprio di risolvere questa problematica offrendo la possibilità di incapsulare all'interno di un Record altri Record figli creando una struttura logica coerente che permetta di ragionare mantenendo una struttura ad oggetti e allo stesso tempo sfruttando le API esposte dalla classe Ext.data.Record. Ritornando all'esempio di prima possiamo riscrivere il tutto cosi:
var Macchina = Ext.ux.data.XRecord.create({ { name: 'manufacturer', type: 'string' }, { name: 'model', type: 'string' } }); var Persona = Ext.ux.data.XRecord.create({ { name: 'firstname', type: 'string' }, { name: 'lastname', type: 'string' }, { name: 'age', type: 'int' }, { name: 'car', type: 'record', record:'Macchina' } }); var persona = ... //ottengo il Record da un apposito Reader var car = persona.get("car") car.get("manufacturer") //ritornerà "BMW" car.get("model") //ritornerà "SLK"
Il plugin semplicemente aggiunge due nuove tipologie di campo disponibili in fase di definizione di un Record: record (per definire un attributo composto da un sotto-record) e recordarray (per un attributo composto da un vettore di sotto-record). Entrambe le definizioni necessitano di un campo aggiuntivo obbligatorio (record) che contiene un riferimento alla tipologia di record che verrà incapsulato (sia un riferimento diretto sia una stringa). Definendo i campi in questo modo sarà possibile lavorare direttamente sui Record utilizzando le stesse API esposte da ExtJS.
Questo nuovo approccio altera a fondo la gestione globale dei Record all'interno di tutto il framework quindi il plugin non solo definisce la classe Ext.ux.data.XRecord, ma presenta anche degli override ad alcune altre classi per permettere l'adattamento a questo nuovo modello di gestione dei dati. Attualmente sono state modificate anche le seguenti classi: