Ext.ux.data.XRecord

ExtJS, Record e associazioni

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:

  • usare la proprietà mapping per creare dei campi custom che incapsulano i campi dell'oggetto car

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' }
});

  • mappare la proprietà car non utilizzando nessuna conversione apposita

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:

  • nel primo caso però siamo abbastanza limitati con la definizione di strutture gerarchiche complesse (basti pensare al comunissimo caso in cui un entità abbia come attributi una lista di altri oggetti).
  • nel secondo invece si viene a creare una sorta di disallineamento tra i vari oggetti nel cui il più “esterno” (nel nostro caso la Persona) è rappresentato come un Ext.data.Record mentre gli oggetti più “interni” sono dei semplici Object.

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"

La soluzione proposta

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:

  • Ext.data.Field: nuovi type: record e recordarray e nuove funzioni di conversione
  • Ext.data.DataWriter: modifica alla funzione di conversione di un record in un hash (aggiunta la ricorsione per trasformare in hash anche i sotto-record)

Download

 
sviluppo/javascript/ext.xrecord.txt · Last modified: 2011/05/10 11:42 (external edit)
 
Except where otherwise noted, content on this wiki is licensed under the following license:CC Attribution-Noncommercial-Share Alike 3.0 Unported
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki