Search code examples
extjsdynamicextjs4

Dynamically generated metadata does not display grid


The following data is being used to load and display a grid dynamically. The only difference between the two grids is that the first reader takes in the data below as is, but the second grid only knows about the data and the metaData will be generated on the fly. I placed stubs for the fields and columns as this is not the issue and I haven't decided on how I will generate the data yet.

Both of the readers eventually pass the data below to the JsonReader's readRecords()' function via this.callParent([data]);, but the second one does not display the data. The data is there, but I am not sure why it does not display?

enter image description here

There are two links to demos below. The first is a JSFiddle that loads from memory and the second is a Sencha Fiddle that loads through AJAX.

Snippet

var rawFields = [
    { "name": "year",     "type": "int" },
    { "name": "standard", "type": "string" },
    { "name": "bitRate",  "type": "float" }
];

var rawColumns = [
    { "text" : "Year",     "dataIndex" : "year",     "flex" : 1 },
    { "text" : "Standard", "dataIndex" : "standard", "flex" : 1 },
    { "text" : "Bit/Sec",  "dataIndex" : "bitRate",  "flex" : 1 }
];
Ext.define('Example.reader.DynamicReader', {
    extend : 'Ext.data.reader.Json',
    alias : 'reader.dynamicReader',

    readRecords : function(data) {
        var response = {
            data: data,
            metaData : this.createMetaData(data),
            success: true
        };
        console.log(response);
        return this.callParent([response]);
    },

    createMetaData : function(data) {
        return {
            idProperty : "id",
            fields : rawFields,  // These will eventually be generated...
            columns : rawColumns // These will eventually be generated...
        };
    }
});

Data

{
    "data": [
        {
            "id": 0,
            "year": 1997,
            "standard": "802.11",
            "bitRate": 2000000
        },
        {
            "id": 1,
            "year": 1999,
            "standard": "802.11b",
            "bitRate": 11000000
        },
        {
            "id": 2,
            "year": 1999,
            "standard": "802.11a",
            "bitRate": 54000000
        },
        {
            "id": 3,
            "year": 2003,
            "standard": "802.11g",
            "bitRate": 54000000
        },
        {
            "id": 4,
            "year": 2007,
            "standard": "802.11n",
            "bitRate": 600000000
        },
        {
            "id": 5,
            "year": 2012,
            "standard": "802.11ac",
            "bitRate": 1000000000
        }
    ],
    "metaData": {
        "idProperty": "id",
        "fields": [
            {
                "name": "year",
                "type": "int"
            },
            {
                "name": "standard",
                "type": "string"
            },
            {
                "name": "bitRate",
                "type": "float"
            }
        ],
        "columns": [
            {
                "text": "Year",
                "dataIndex": "year",
                "flex": 1
            },
            {
                "text": "Standard",
                "dataIndex": "standard",
                "flex": 1
            },
            {
                "text": "Bit/Sec",
                "dataIndex": "bitRate",
                "flex": 1
            }
        ],
        "success": true
    }
} 

Demos

The following examples both achieve the same thing, so the only difference is the loading of the data.

Loading from Memory

http://jsfiddle.net/MrPolywhirl/zy4z5z8a/

Loading from AJAX

https://fiddle.sencha.com/#fiddle/d3l


Solution

  • I figured out the answer. I needed to specify a root value for the reader so that the data can be mapped properly.

    Ext.onReady(function() {
        Ext.widget("dynamicGrid", {
            title: 'WiFi LAN Data Rates [Dynamic]',
            renderTo: Ext.get('example-grid-dynamic'),
            readerType: 'dynamicReader',
            // This need to match the 'data' key specified in the `response` object
            // that was created in readRecords().
            readerRoot: 'data',
            data : rawData
        });
    });
    

    The documentation for root notes that the root property has to map to the data portion of the response.

    Documentation for Json.root:

    Ext.data.reader.Json.root

    root : String

    The name of the property which contains the data items corresponding to the Model(s) for which this Reader is configured. For JSON reader it's a property name (or a dot-separated list of property names if the root is nested). For XML reader it's a CSS selector. For Array reader the root is not applicable since the data is assumed to be a single-level array of arrays.