2013-04-15 13 views
6

Dettagli

Ho una griglia utilizzata per visualizzare le informazioni di fatturazione. La griglia viene popolata utilizzando lo store di fatturazione, lo store di fatturazione utilizza il modello di fattura, il modello di fattura ha un'associazione "ha uno" con il modello InvoiceStatus con una chiave primaria di "id" e una chiave di foren di "invoice_status_id".EXT JS 4 utilizza un'associazione modello per il rendering di un valore di visualizzazione griglia

Problema

Non sono sicuro di come rendere il valore di visualizzazione della colonna 'Stato' di fattura Griglia utilizzare i modelli associati 'nome' inserito del invoice_status_id. So che ho bisogno di creare un renderer per fare questo, ma ho ancora un valore nullo. Sia gli stori Fattura che InvoiceStatus stanno popolando con i valori corretti.

Colonna Stato Render

renderer: function(value, metaData, record, rowIndex, colIndex, store, view) { 
    return record.getStatus().get('name'); 
}, 

Conservare fattura

Ext.define('MyApp.store.Invoice', { 
    extend: 'Ext.data.Store', 

    requires: [ 
     'MyApp.model.InvoiceModel' 
    ], 

    constructor: function(cfg) { 
     var me = this; 
     cfg = cfg || {}; 
     me.callParent([Ext.apply({ 
      autoLoad: true, 
      autoSync: true, 
      model: 'MyApp.model.InvoiceModel', 
      remoteSort: true, 
      storeId: 'StoreInvoce', 
      proxy: { 
       type: 'rest', 
       url: '/api/invoice', 
       reader: { 
        type: 'json', 
        root: 'data' 
       } 
      } 
     }, cfg)]); 
    } 
}); 

InvoiceStatus Conservare

Ext.define('MyApp.store.InvoiceStatus', { 
    extend: 'Ext.data.Store', 
    alias: 'store.InvoiceStatus', 

    requires: [ 
     'MyApp.model.InvoiceStatus' 
    ], 

    constructor: function(cfg) { 
     var me = this; 
     cfg = cfg || {}; 
     me.callParent([Ext.apply({ 
      autoLoad: true, 
      autoSync: true, 
      model: 'MyApp.model.InvoiceStatus', 
      remoteSort: true, 
      storeId: 'MyJsonStore1', 
      proxy: { 
       type: 'rest', 
       url: '/api/invoice_status', 
       reader: { 
        type: 'json', 
        root: 'data' 
       } 
      } 
     }, cfg)]); 
    } 
}); 

fattura Modello

Ext.define('MyApp.model.InvoiceModel', { 
    extend: 'Ext.data.Model', 

    uses: [ 
     'MyApp.model.InvoiceStatus' 
    ], 

    fields: [ 
     { 
      mapping: 'id', 
      name: 'id', 
      type: 'int' 
     }, 
     { 
      mapping: 'client_id', 
      name: 'client_id', 
      type: 'int' 
     }, 
     { 
      mapping: 'client_name', 
      name: 'client_name', 
      type: 'string' 
     }, 
     { 
      dateFormat: 'Y-m-d', 
      dateReadFormat: '', 
      mapping: 'issue_date', 
      name: 'issue_date', 
      sortType: 'asDate', 
      type: 'date' 
     }, 
     { 
      dateFormat: 'Y-m-d', 
      mapping: 'due_date', 
      name: 'due_date', 
      sortType: 'asDate', 
      type: 'date' 
     }, 
     { 
      mapping: 'payment_date', 
      name: 'payment_date', 
      sortType: 'asDate', 
      type: 'date', 
      useNull: true 
     }, 
     { 
      name: 'amount' 
     }, 
     { 
      mapping: 'invoice_status_id', 
      name: 'invoice_status_id', 
      sortType: 'asInt', 
      type: 'int' 
     } 
    ], 

    hasOne: { 
     model: 'MyApp.model.InvoiceStatus', 
     foreignKey: 'invoice_status_id', 
     getterName: 'getStatus' 
    } 
}); 

InvoiceStatus Modello

Ext.define('MyApp.model.InvoiceStatus', { 
    extend: 'Ext.data.Model', 

    fields: [ 
     { 
      mapping: 'id', 
      name: 'id', 
      type: 'int' 
     }, 
     { 
      mapping: 'name', 
      name: 'name', 
      type: 'string' 
     } 
    ] 
}); 

fattura Griglia

Ext.define('MyApp.view.ApplicationViewport', { 
    extend: 'Ext.container.Viewport', 

    requires: [ 
     'MyApp.view.ClearTriggerField' 
    ], 

    layout: { 
     type: 'border' 
    }, 

    initComponent: function() { 
     var me = this; 

     Ext.applyIf(me, { 
      items: [ 
       { 
        xtype: 'header', 
        region: 'north', 
        height: 100, 
        items: [ 
         { 
          xtype: 'image', 
          height: 100, 
          width: 250, 
          alt: 'Logo', 
          src: 'images/logo.gif', 
          title: 'Logo' 
         } 
        ] 
       }, 
       { 
        xtype: 'container', 
        region: 'center', 
        layout: { 
         type: 'card' 
        }, 
        items: [ 
         { 
          xtype: 'container', 
          width: 150, 
          layout: { 
           type: 'border' 
          }, 
          items: [ 
           { 
            xtype: 'gridpanel', 
            collapseMode: 'mini', 
            region: 'west', 
            split: true, 
            autoRender: false, 
            maxWidth: 300, 
            width: 250, 
            bodyBorder: false, 
            animCollapse: false, 
            collapsed: false, 
            collapsible: true, 
            hideCollapseTool: true, 
            overlapHeader: false, 
            titleCollapse: true, 
            allowDeselect: true, 
            columnLines: false, 
            forceFit: true, 
            store: 'ClientDataStor', 
            dockedItems: [ 
             { 
              xtype: 'toolbar', 
              dock: 'top', 
              items: [ 
               { 
                xtype: 'cleartrigger' 
               }, 
               { 
                xtype: 'tbfill' 
               }, 
               { 
                xtype: 'button', 
                icon: '/images/settings.png' 
               } 
              ] 
             } 
            ], 
            columns: [ 
             { 
              xtype: 'templatecolumn', 
              tpl: [ 
               '<img class="pull-left client-menu-image" src="/images/{type}.png"><div class="client-menu-name">{name}</div><div class="client-menu-type">{type}</div>' 
              ], 
              dataIndex: 'id', 
              text: 'Client' 
             } 
            ], 
            selModel: Ext.create('Ext.selection.RowModel', { 

            }), 
            plugins: [ 
             Ext.create('Ext.grid.plugin.BufferedRenderer', { 

             }) 
            ] 
           }, 
           { 
            xtype: 'gridpanel', 
            region: 'center', 
            title: 'Invoices', 
            titleCollapse: false, 
            forceFit: true, 
            store: 'Invoice', 
            columns: [ 
             { 
              xtype: 'numbercolumn', 
              maxWidth: 120, 
              minWidth: 50, 
              dataIndex: 'id', 
              groupable: false, 
              lockable: true, 
              text: 'ID', 
              tooltip: 'Invoice ID', 
              format: '0' 
             }, 
             { 
              xtype: 'numbercolumn', 
              hidden: true, 
              maxWidth: 120, 
              minWidth: 50, 
              dataIndex: 'client_id', 
              groupable: true, 
              text: 'Client ID', 
              format: '0' 
             }, 
             { 
              xtype: 'gridcolumn', 
              renderer: function(value, metaData, record, rowIndex, colIndex, store, view) { 
               return record.getStatus().get('name'); 
              }, 
              maxWidth: 200, 
              minWidth: 100, 
              dataIndex: 'invoice_status_id', 
              text: 'Status' 
             }, 
             { 
              xtype: 'datecolumn', 
              maxWidth: 200, 
              minWidth: 100, 
              dataIndex: 'issue_date', 
              text: 'Issue Date', 
              format: 'd M Y' 
             }, 
             { 
              xtype: 'datecolumn', 
              maxWidth: 200, 
              minWidth: 100, 
              dataIndex: 'due_date', 
              text: 'Due Date', 
              format: 'd M Y' 
             }, 
             { 
              xtype: 'datecolumn', 
              maxWidth: 200, 
              minWidth: 100, 
              dataIndex: 'payment_date', 
              text: 'Payment Date', 
              format: 'd M Y' 
             }, 
             { 
              xtype: 'templatecolumn', 
              summaryType: 'sum', 
              maxWidth: 150, 
              minWidth: 50, 
              tpl: [ 
               '${amount}' 
              ], 
              defaultWidth: 80, 
              dataIndex: 'amount', 
              groupable: true, 
              text: 'Amount' 
             } 
            ], 
            features: [ 
             { 
              ftype: 'grouping' 
             } 
            ] 
           } 
          ] 
         } 
        ] 
       } 
      ] 
     }); 

     me.callParent(arguments); 
    } 

}); 
+0

Ho anche provato questo nel mio renderer di colonna store.getAt (rowIndex) .getStatus(). Get ('nome'); –

risposta

10

Sono riuscito a far funzionare la ricerca dell'associazione utilizzando una funzione di callback, ma ho trovato molto più facile semplicemente la ricerca dal negozio stesso.

Fase uno

ho spostato il proxy dal negozio InvoiceStatus e sul modello InvoiceStatus e ha reso il negozio di caricamento automatico InvoiceStatus.

Fase due

ho cambiato il metodo di rendering della colonna Stato per cercare il nome visualizzato dal negozio InvoiceStatus in questo modo.

renderer: function(value, metaData, record, rowIndex, colIndex, store, view) { 
    var store = Ext.data.StoreManager.lookup('InvoiceStatus'); 
    return store.getById(value).get('name'); 
}, 

Questo ha dimostrato di essere una soluzione molto simpeler.

+0

buona soluzione! Grazie. Obs: ricorda di controllare i valori nulli per evitare errori, ad es. If (value && value> 0) {/*...*/} –

3

Sembra che è necessario impostare il belongsTo associazione sulla InvoiceStatus chi ld modello. Si potrebbe pensare che la definizione dell'associazione in una direzione creerebbe automaticamente l'associazione nella direzione opposta, ma a quanto pare non è così e si deve definire l'associazione su entrambi i genitori e i figli. Vedi qui per una spiegazione più dettagliata: Why isn't my ExtJS Store Association Working

+0

Grazie James, questo era parte della risposta. Il vero problema era che il mio negozio associato era un negozio json e doveva essere caricato prima che il valore potesse essere aggiunto. Ciò richiedeva un metodo di callback come parte della funzione di rendering, questo fatto per un processo di caricamento disordinato e ho trovato un metodo più semplice per il rendering dei valori di ricerca. Vedi la mia risposta. –

3

tuo hasOne dovrebbe essere simile a questo:

hasOne: { 
    name:   'status', 
    instanceName: 'status', 
    associationKey: 'status', 
    model:   'MyApp.model.InvoiceStatus', 
    foreignKey:  'invoice_status_id', 
    getterName:  'getStatus', 
    setterName:  'setStatus' 
} 

La seguente patch per ExtJS 4.2.2 vi permetterà di impostare dataIndex: 'status.name' senza renderer aggiuntivi. La griglia mostrerà tutto OK ma l'ordinamento non funzionerà.

Questa soluzione non funziona con il carico di stato asincrono (pigro).

Ext.view.Table.prototype.renderCell = function(column, record, recordIndex, rowIndex, columnIndex, out) { 
    var me = this, 
     selModel = me.selModel, 
     cellValues = me.cellValues, 
     classes = cellValues.classes, 
     // fieldValue = record.data[column.dataIndex]; // patched 
     fieldValue = null, 
     cellTpl = me.cellTpl, 
     fullIndex, value, clsInsertPoint; 

    // Patch start 
    if (column.dataIndex && column.dataIndex.indexOf('.') > 0) { 
     var associationParts = column.dataIndex.split('.'), 
      v = record; 

     for (var i = 0; i < associationParts.length-1; i++) { 
      v = v['get' + associationParts[i].charAt(0).toUpperCase() + associationParts[i].slice(1)](); 
     } 
     fieldValue = v.get(associationParts[associationParts.length-1]); 
    } 
    else { 
     fieldValue = record.data[column.dataIndex]; 
    } 
    // Patch end 

    cellValues.record = record; 
    cellValues.column = column; 
    cellValues.recordIndex = recordIndex; 
    cellValues.rowIndex = rowIndex; 
    cellValues.columnIndex = columnIndex; 
    cellValues.cellIndex = columnIndex; 
    cellValues.align = column.align; 
    cellValues.tdCls = column.tdCls; 
    cellValues.innerCls = column.innerCls; 
    cellValues.style = cellValues.tdAttr = ""; 
    cellValues.unselectableAttr = me.enableTextSelection ? '' : 'unselectable="on"'; 

    if (column.renderer && column.renderer.call) { 
     fullIndex = me.ownerCt.columnManager.getHeaderIndex(column); 
     value = column.renderer.call(column.scope || me.ownerCt, fieldValue, cellValues, record, recordIndex, fullIndex, me.dataSource, me); 
     if (cellValues.css) { 
      // This warning attribute is used by the compat layer 
      // TODO: remove when compat layer becomes deprecated 
      record.cssWarning = true; 
      cellValues.tdCls += ' ' + cellValues.css; 
      delete cellValues.css; 
     } 
    } else { 
     value = fieldValue; 
    } 
    cellValues.value = (value == null || value === '') ? '&#160;' : value; 

    // Calculate classes to add to cell 
    classes[1] = column.getCellId(); 

    // On IE8, array[len] = 'foo' is twice as fast as array.push('foo') 
    // So keep an insertion point and use assignment to help IE! 
    clsInsertPoint = 2; 

    if (column.tdCls) { 
     classes[clsInsertPoint++] = column.tdCls; 
    } 
    if (me.markDirty && record.isModified(column.dataIndex)) { 
     classes[clsInsertPoint++] = me.dirtyCls; 
    } 
    if (column.isFirstVisible) { 
     classes[clsInsertPoint++] = me.firstCls; 
    } 
    if (column.isLastVisible) { 
     classes[clsInsertPoint++] = me.lastCls; 
    } 
    if (!me.enableTextSelection) { 
     classes[clsInsertPoint++] = me.unselectableCls; 
    } 
    if (cellValues.tdCls) { 
     classes[clsInsertPoint++] = cellValues.tdCls; 
    } 
    if (selModel && selModel.isCellModel && selModel.isCellSelected(me, recordIndex, columnIndex)) { 
     classes[clsInsertPoint++] = (me.selectedCellCls); 
    } 

    // Chop back array to only what we've set 
    classes.length = clsInsertPoint; 

    cellValues.tdCls = classes.join(' '); 

    cellTpl.applyOut(cellValues, out); 

    // Dereference objects since cellValues is a persistent var in the XTemplate's scope chain 
     cellValues.column = null; 
}; 
Problemi correlati