2013-04-15 13 views
6

Ayrıntılar

Fatura bilgilerini görüntülemek için kullanılan bir ızgaram var. Fatura, Fatura deposunu kullanarak doldurulur; Fatura deposu Fatura modelini kullanır, Fatura modeli, 'id' anahtarının ve 'invoice_status_id' anahtar anahtarının bulunduğu InvoiceStatus modeli ile "bir tane vardır" ilişkisine sahiptir.EXT JS 4 ızgara görünüm değeri oluşturmak için bir model ilişkilendirmesi kullanın

Sorun

Ben Fatura Grid 'Durum' sütununda görünen değeri invoice_status_id ait takılan ilişkili modeller 'adını' kullanan nasıl emin değilim. Bunu yapmak için bir oluşturucu oluşturmam gerektiğini biliyorum, ancak hala boş bir değer elde ediyorum. Fatura ve InvoiceStatus stors değerleri doğru değerlerle doldurulur.

Durum Sütunu Render

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

Fatura Mağaza

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 Mağaza

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

Fatura Modeli

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 Modeli

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

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

Fatura Izgara

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

Ayrıca bunu sütun oluşturucu store.getAt (rowIndex) .getStatus() 'da denedim (' name '); –

cevap

10

Geri arama işlevini kullanarak ilişkilendirme aramayı çalışmayı başardım, ancak aramayı mağazanın kendim yapmasını çok daha kolay buldum. Bir

Adım I InvoiceStatus modeli InvoiceStatus deposundan ve üzerine Vekil taşındı ve InvoiceStatus deposu AutoLoad yaptı. İki

Adım I şöyle InvoiceStatus deposundan görünen adı arama için Durum sütununun hale yöntemini değiştirdi.

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

Bu, çok basit bir çözüm olduğunu kanıtlamıştır.

+0

güzel bir çözüm! Teşekkürler. Obs: Hatalardan kaçınmak için boş değerleri kontrol etmeyi unutmayın, örneğin: if (value && value> 0) {/*...*/} –

3

Eğer InvoiceStatus chi belongsTo dernek ayarlamak gerekir gibi görünüyor ld modeli. Derlemeyi bir yönde tanımlamanın derneği diğer yönde otomatik olarak yaratacağını düşünebilirsiniz, ancak görünüşe göre bu durum böyle değildir ve hem ebeveyn hem de çocuklar arasındaki ilişkiyi tanımlamanız gerekir. Daha ayrıntılı bir açıklama için buraya bakın: Why isn't my ExtJS Store Association Working

+0

Teşekkürler James, bu cevabın bir parçasıydı. Asıl sorun, ilgili mağazamın bir json deposu olması ve ondan alınabilecek değerden önce yüklenmesi gerektiğiydi. Bu, render işlevinin bir parçası olarak geri arama yöntemini gerektirdi, bu da dağınık bir yükleme işlemi için yapıldı ve arama değerlerini oluşturmanın daha kolay bir yöntemini bulmayı başardım. Cevabımı gör. –

3

Kişisel hasOne böyle olmalı:

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

ExtJS 4.2.2 için aşağıdaki yama herhangi bir ek render olmadan dataIndex: 'status.name' set izin verir. Izgara herşeyi gösterecek ama sıralama işe yaramayacak.

Bu çözüm, uyumsuz (tembel) durum yüküyle çalışmaz.

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; 
}; 
İlgili konular