How to display nested objects in a GridPanel in ExtJS (and Sencha architect)?

5.9k views Asked by At

I've got an incoming array of Offering objects that looks like this:

[{
  "id" : 16,
  "price" : 500,
  "quantity" : 2000,
  "denomination" : "case",
  "denominationPlural" : "cases",
  "product" : {
    "id" : 14,
    "description" : "This is the text description for product 14."
  }
}, {
  "id" : 18,
  "price" : 500,
  "quantity" : 1,
  "denomination" : "study",
  "denominationPlural" : "studies",
  "product" : {
    "id" : 17,
    "description" : "This is a text description for product 17."
  }
}]

An Offering is a Product times a quantity for a price.

Now I want to display these Offerings in a GridPanel, but also include the nested product information in those rows. Here's how I was doing it before:

Ext.define('Offering', {
            extend: 'Ext.data.Model',
            fields: [
                {name: 'id', type: 'number'},
                {name: 'price', type: 'number'},
                {name: 'quantity', type: 'number'},
                {name: 'denomination', type: 'string'},
                {name: 'denominationPlural', type: 'string'},
                {name: 'product.description', type: 'string'},
            ]
        });



var offeringStore = Ext.create('Ext.data.Store', {
             autoDestroy: true,
             model: 'Offering',
             proxy: {
                 type: 'ajax',
                 url: '/offerings',
                 reader: {
                     type: 'json',
                     root: 'success'
                 }
             },
             autoLoad:true
         });

var offeringGrid = Ext.create('Ext.grid.Panel', {
            store: offeringStore,
            columns: [{
                    header: 'id',
                    dataIndex: 'id'
                }, {
                    header: 'price',
                    dataIndex: 'price'
                }, {
                    header: 'quantity',
                    dataIndex: 'quantity'
                }, {
                    header: 'denomination',
                    dataIndex: 'denomination'
                }, {
                    header: 'description',
                    dataIndex: 'product.description'
                },
            };

And this worked just fine. Then, somewhere along the way (which included an upgrade to ExtJS 5.1.1 (from ExtJS 4.2.1) and use of Sencha Architect, it broke.

Problem 1: Sencha Architect prevents creating an entry for "product.description" in the Offering Model, complaining about the "." character. But if you create it as "whateveryouwant", you can go into the model field and rename it to "product.description" there.

Problem 2: after working around the "." issue and running the application, the "product.description" column's cells are blank.

Problem 3: the javascript console produces zero errors. The incoming data looks fine.

How should I go about getting this nested data to show up?

2

There are 2 answers

2
Akash Rajbanshi On BEST ANSWER

The way I do it is quite simple. Just add the mapping attribute to the model this way:

{
    name: 'product.description', 
    type: 'string',
    mapping : 'product.description'
}

No need for renderer.

0
fivedogit On

My current workaround, which may help others in the same situation, uses a "renderer" clause to display the information desired.

{
    xtype: 'gridpanel',
    title: 'Offerings',
    bind: {
        store: '{OfferingsStore}'
    },
    columns: [
            ...
            {
                xtype: 'gridcolumn',
                renderer: function(value, metaData, record, rowIndex, colIndex, store, view) {
                    return record.getData().product.description;
                },
                text: 'Product Description'
            },
            ...
      ]

But I'd still like an answer about using "product.description" in the Offering Model definition rather than this rendering trick.