简体   繁体   English

使用ExtJS创建动态网格

[英]Creating a Dynamic Grid with ExtJS

I'm trying to make a Dynamic Grid class (where I do not know any information about the columns but they are given from the json response and the gird prepares itself accordingly). 我正在尝试创建一个动态网格类(我不知道有关列的任何信息,但它们是从json响应中给出的,并且网格相应地准备自己)。 Here I have found exactly what I was looking for however it gives me an error: 在这里,我找到了我正在寻找的东西,但它给了我一个错误:

me.model is undefined
me.setProxy(me.proxy || me.model.getProxy());
ext-all-debug.js (line 47323)

I have tried to add both proxy and model but I was not successful, I kept getting the same error. 我试图添加代理和模型,但我没有成功,我一直得到同样的错误。

Here is the ExtJS code that I'm working on: 这是我正在研究的ExtJS代码:

 // ExtJS 4.1
 Ext.Loader.setConfig({
     enabled: true
 });
 Ext.Loader.setPath('Ext.ux', '../extjs-4.1.0/examples/ux');
 Ext.require([
     'Ext.grid.*',
     'Ext.data.*', ]);


 Ext.define('DynamicGrid', {
     extend: 'Ext.grid.GridPanel',
     storeUrl: '',
     enableColumnHide: true,
     initComponent: function () {
         var store = new Ext.data.Store({
             url: this.storeUrl,
             reader: new Ext.data.JsonReader(),
             autoLoad: true,
             scope: this,
             listeners: {
                 scope: this,
                 metachange: function (store, meta) {
                     if (typeof (store.reader.jsonData.columns) === 'object') {
                         var columns = [];
                         /**
                          * Adding RowNumberer or setting selection model as CheckboxSelectionModel
                          * We need to add them before other columns to display first
                          */
                         if (this.rowNumberer) {
                             columns.push(new Ext.grid.RowNumberer());
                         }
                         if (this.checkboxSelModel) {
                             columns.push(new Ext.grid.CheckboxSelectionModel());
                         }
                         Ext.each(store.reader.jsonData.columns, function (column) {
                             columns.push(column);
                         }); // Set column model configuration 
                         this.getColumnModel().setConfig(columns);
                         this.reconfigure(store, this.getColumnModel());
                     }
                 }
             }
         });
         var config = {
             title: 'Dynamic Columns',
             viewConfig: {
                 emptyText: 'No rows to display'
             },
             loadMask: true,
             border: false,
             stripeRows: true,
             store: store,
             columns: []
         }
         Ext.apply(this, config);
         Ext.apply(this.initialConfig, config);
         DynamicGrid.superclass.initComponent.apply(this, arguments);
     },
     onRender: function (ct, position) {
         this.colModel.defaultSortable = true;
         DynamicGrid.superclass.onRender.call(this, ct, position);
     }
 });

 Ext.onReady(function () {

     Ext.QuickTips.init();

     var grid = Ext.create('DynamicGrid', {
         storeUrl: 'http://300.79.103.188/ApplicationJs/jsontest.json'
     });

     var depV = Ext.create('Ext.Viewport', {
         title: 'Departman Tanımları',
         layout: 'fit',
         items: grid
     }).show();

 });

What I have to do inorder to make it run? 为了让它运行,我必须做些什么?

That is a pretty old post so you may have more workarounds coming soon, but that error is because you do not have a model config or fields config defined for your store. 这是一篇非常古老的帖子,因此您很快就会有更多的解决方法,但该错误是因为您没有为您的商店定义模型配置字段配置 The model will also need to be defined dynamically if you want your grid created with json data alone. 如果您希望仅使用json数据创建网格,则还需要动态定义模型。

As far as I know, the fields config is pretty forgiving, so you may be able to just set this with a maximum possible number of fields like 20 or 30 or so, but the field names would have to match with the json field names for it to be usable. 据我所知,字段配置是非常宽容的,所以你可以设置最大可能数量的字段,如20或30左右,但字段名称必须与json字段名称匹配它是可用的。 Ie if you use: 即如果您使用:

var store = new Ext.data.Store({
    url: this.storeUrl,
    reader: new Ext.data.JsonReader(),
    fields: [
        'column1',
        'column2',
        'column3',
        'column4',
        'column5',
        // etc
    ],

Then your json data would need to come from the database like: 然后你的json数据需要来自数据库,如:

[{"column1":"data1", "column2":"data2", // etc

Another thing I've done in the past is to have a reference store loaded first which contained a record with the name and datatype for each of the dynamic fields (meta data). 我过去做过的另一件事是首先加载一个引用存储,它包含一个记录,其中包含每个动态字段(元数据)的名称和数据类型。 Then I iterated through this reference store and added a model field and the column definition at each iteration, then I loaded the grid's store which now had the correct data model defined and the grid would have the correct column defintion. 然后我遍历这个引用存储并在每次迭代时添加了一个模型字段 列定义, 然后我加载了网格的存储,该存储现在已经定义了正确的数据模型,并且网格将具有正确的列定义。

You may have do something like that if you don't want to make your database return generic column names as covered above, because I don't know how you will load the data into your grid store initially before you give it a data model to use. 如果您不想让数据库返回上面所述的通用列名,您可能会做类似的事情,因为我不知道如何在将数据模型提供给数据模型之前将数据加载到网格存储中使用。

UPDATE 13 Jun: 6月13日更新:

I haven't tried it yet, but I just came across this in the 4.1 docs (scroll down to the "Response MetaData" section in the intro). 我还没有尝试过,但我刚刚在4.1文档中看到了这一点 (向下滚动到介绍中的“响应元数据”部分)。 It describes using metaData in your json response to accomplish exactly what you are going for with a dynamic model and grid columns. 它描述了在json响应中使用metaData,以使用动态模型和网格列完全实现您的目标。

You would probably still have to do the iteration I described above once you process the metaData, but you can use it to cut out that additional request to get the meta data. 一旦处理完metaData,您可能仍然需要执行上面描述的迭代,但您可以使用它来删除获取元数据的额外请求。

I suppose if your field configuration doesn't change with each request then it would be easier to simply to do the extra request at the beginning, but if you want something really dynamic this would do it. 我想如果你的字段配置不会随着每个请求而改变,那么在开始时简单地做额外的请求会更容易,但如果你想要一些非常动态的东西,那就可以了。

NOTE : This is a duplicte to my response here : How do you create table columns and fields from json? 注意 :这是我的响应的重复: 如何从json创建表列和字段? (Dynamic Grid) . (动态网格) I just wanted address my final solution in all of the StackOverflow questions I used to solve this problem. 我只想在解决这个问题的所有StackOverflow问题中解决我的最终解决方案。

Stackoverflow is littered with questions very similar to this one. Stackoverflow充斥着与此非常类似的问题。 I worked through them all and did not find a definitive solution. 我完成了所有工作并没有找到明确的解决方案。 However, most of the provided answers pointed me in the right direction. 但是,大多数提供的答案都指出了我正确的方向。 I'll give me best shot at putting all those suggestions together and making this clear for others: 我会尽最大努力将所有这些建议放在一起并为其他人明确表达:

Model: (Only shows 2 fields that will be in all JSON responses. Will still be overwritten) 型号:(仅显示将在所有JSON响应中的2个字段。仍将被覆盖)

Ext.define('RTS.model.TestsModel', {
    extend: 'Ext.data.Model',
    alias: 'model.TestsModel',

    fields: [
        {
            name: 'poll_date'
        },
        {
            name: 'poller'
        }
    ]
});

Store: 商店:

Ext.define('RTS.store.TestsStore', {
    extend: 'Ext.data.Store',
    alias: 'store.TestsStore',

    model: 'RTS.model.TestsModel',

    constructor: function(cfg) {
        var me = this;

        cfg = cfg || {};

        me.callParent([Ext.apply({
            autoLoad: false,
            proxy       : {
                type    : 'ajax',
                url     : 'tests.php',
                reader  : {
                    type    : 'json',
                    root    : 'tests',
                    successProperty : 'success'
                }
            },            
            storeId: 'tests-store'
        }, cfg)]);
    }
});

View: (The columns will be defined in each JSON response) 视图:(列将在每个JSON响应中定义)

Ext.define('RTS.view.TestsView', {
    extend: 'Ext.grid.Panel',
    alias: 'widget.TestsView',

    id: 'tests-view',
    title: 'Tests',
    emptyText: '',
    store: 'TestsStore',

    initComponent: function() {
        var me = this;

        Ext.applyIf(me, {
            viewConfig: {

            },
            columns: [
            ]
        });

        me.callParent(arguments);
    }

});

Controller: (The controller does all the work in forcing the view and model to change based on the JSON response). 控制器:(控制器完成所有工作,强制视图和模型根据JSON响应进行更改)。

Ext.define('RTS.controller.TestsController', {
    extend: 'Ext.app.Controller',
    alias: 'controller.TestsController',

    stores: [
        'TestsStore'
    ],
    models: [
        'TestsModel'
    ],
    views: [
        'TestsView'
    ],

    init: function(application) {

        // When store changes, trigger an event on grid
        // to be handled in 'this.control'.  

        // NOTE : Ext JS does not allow control of 
        // non-component events.

        // Ext JS 4.2 beta will allow the controller
        // to detect non-component changes and handle them
        var testsStore = this.getStore('TestsStore');
        testsStore.on("metachange", metaChanged, this);
        function metaChanged(store, meta) {
            var grid = Ext.ComponentQuery.query('TestsView')[0];
            grid.fireEvent('metaChanged', store, meta);
        };


        this.control({
            "TestsView": {
                metaChanged: this.handleStoreMetaChange
            }
        });
    },

    /**
     * Will update the model with the metaData and
     * will reconfigure the grid to use the
     * new model and columns.
     */
    handleStoreMetaChange: function(store, meta) {
        var testsGrids = Ext.ComponentQuery.query('TestsView')[0];
        testsGrids.reconfigure(store, meta.columns);
    }

});

JSON Response: Your json response must have the "metaData" property included. JSON响应:您的json响应必须包含“metaData”属性。 It should define the fields just as you would on a static model and the view that would normally be defined to show the fields. 它应该像在静态模型上一样定义字段,并且通常定义为显示字段的视图。

{
    "success": true,
    "msg": "",
    "metaData": {
        "fields": [
            {
                "name": "poller"
            },
            {
                "name": "poll_date"
            },
            {
                "name": "PING",
                "type": "int"
            },
            {
                "name": "SNMP",
                "type": "int"
            },
            {
                "name": "TELNET",
                "type": "int"
            },
            {
                "name": "SSH",
                "type": "int"
            },
            {
                "name": "all_passed"
            }
        ],
        "columns": [
            {
                "dataIndex": "poller",
                "flex": 1,
                "sortable": false,
                "hideable": false,
                "text": "Poller"
            },
            {
                "dataIndex": "poll_date",
                "flex": 1,
                "sortable": false,
                "hideable": false,
                "text": "Poll Date"
            },
            {
                "dataIndex": "PING",
                "flex": 1,
                "sortable": false,
                "hideable": false,
                "text": "PING",
                "renderer": "RenderFailedTests"
            },
            {
                "dataIndex": "SNMP",
                "flex": 1,
                "sortable": false,
                "hideable": false,
                "text": "SNMP",
                "renderer": "RenderFailedTests"
            },
            {
                "dataIndex": "TELNET",
                "flex": 1,
                "sortable": false,
                "hideable": false,
                "text": "TELNET",
                "renderer": "RenderFailedTests"
            },
            {
                "dataIndex": "SSH",
                "flex": 1,
                "sortable": false,
                "hideable": false,
                "text": "SSH",
                "renderer": "RenderFailedTests"
            },
            {
                "dataIndex": "all_passed",
                "flex": 1,
                "sortable": false,
                "hideable": false,
                "text": "All Passed",
                "renderer": "RenderFailedTests"
            }
        ]
    },
    "tests": [
        {
            "poller": "CHI",
            "poll_date": "2013-03-06",
            "PING": "1",
            "SNMP": "0",
            "TELNET": "1",
            "SSH": "0",
            "all_passed": "0"
        },
        {
            "poller": "DAL",
            "poll_date": "2013-03-06",
            "PING": "1",
            "SNMP": "0",
            "TELNET": "1",
            "SSH": "0",
            "all_passed": "0"
        },
        {
            "poller": "CHI",
            "poll_date": "2013-03-04",
            "PING": "1",
            "SNMP": "0",
            "TELNET": "1",
            "SSH": "0",
            "all_passed": "0"
        },
        {
            "poller": "DAL",
            "poll_date": "2013-03-04",
            "PING": "1",
            "SNMP": "0",
            "TELNET": "1",
            "SSH": "0",
            "all_passed": "0"
        },
        {
            "poller": "CHI",
            "poll_date": "2013-03-01",
            "PING": "1",
            "SNMP": "0",
            "TELNET": "1",
            "SSH": "0",
            "all_passed": "0"
        }
    ]
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM