从服务器端动态检索 GridPanel 模型/存储/列 [英] Retrieve GridPanel model/store/columns dynamically from server side

查看:16
本文介绍了从服务器端动态检索 GridPanel 模型/存储/列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 GridPanel,它必须在 DB SP 返回表的列之后动态创建其存储模型和列模型.

I have a GridPanel that must have its store model AND column model created dynamically, after a DB SP returns the columns of the table.

我的问题是如何将值(字符串或 JSON)从服务器传递到 GridPanel?

My question is how can I pass the value ( string or JSON )s from the server to the GridPanel?

Ext.define('Base.GridPanel', {
    extend: 'Ext.grid.Panel',
    xtype: 'gridpanel',

    flex: @BFE.Frontend.Defaults.BaseGridPanel.flex,
    hideMode: '@BFE.Frontend.Defaults.BaseGridPanel.hideMode',

    collapsible: true,

    constructor: function(id, title, columns, store) 
    {
        this.id = id;
        this.title = title;
        this.columns = columns;
        this.store = store;

        this.callParent();
    }
});

我现在使用这个自定义的 GridPanel 以及以下模型和存储.

I use this custom defined GridPanel along with the following model and store for now.

Ext.define('Tasks', {
    extend: 'Ext.data.Model',

    fields: 
    [
        {name: 'Case_ID', type: '@MCSJS.Models.DataType.Auto'},
        {name: 'BP_Name', type: '@MCSJS.Models.DataType.Auto'},
        {name: 'Project', type: '@MCSJS.Models.DataType.Auto'},
        {name: 'Business_Unit', type: '@MCSJS.Models.DataType.Auto'},
        {name: 'Task', type: '@MCSJS.Models.DataType.Auto'},
        {name: 'Title', type: '@MCSJS.Models.DataType.Auto'},
        {name: 'Last_Edit', type: '@MCSJS.Models.DataType.Auto'},
        {name: 'Entity_Name', type: '@MCSJS.Models.DataType.Auto'},
        {name: 'Process_Instance_ID', type: '@MCSJS.Models.DataType.Auto'},
        {name: 'Start_of_Business', type: '@MCSJS.Models.DataType.Auto'},
        {name: 'Last_User', type: '@MCSJS.Models.DataType.Auto'}
    ]
});

var myTaskStore = Ext.create('Ext.data.Store', {
    storeId: 'myTasks',
    model: 'Tasks',
    autoLoad: true,
    proxy:  
    {
        type: 'ajax',
        url: '/Task/GetMyTaskData',
        reader: 
        {
            type: 'json',
            root: 'data'
        }
    }
});

这就是我创建 GridPanel 的方式:

This is how I create a GridPanel :

var columns = [ { text: 'Case ID', dataIndex: 'Case_ID' },
                { text: 'BP Name', dataIndex: 'BP_Name' } ];
new Base.GridPanel('@BFE.Frontend.MyTask.GridPanel', 'My Tasks', columns, myTaskStore)

推荐答案

Ext 为此提供了一些支持.您可以通过添加一个 metaData 属性到服务器响应.您可以使用 metaProperty 选项.

Ext provides some support for that. You can send the model configuration by adding a metaData property to the server response. You can configure the name of the property with the metaProperty option.

文档没有说清楚,但您可以通过这种方式重新配置模型的字段.以下是可以做到这一点的响应:

The documentation doesn't make it obvious, but you can reconfigure the fields of the model this way. Here's the kind of response that would do that:

{
    data: [...]

    ,metaData: {
        // This will be recognized and processed automatically
        // by the proxy
        fields: [
            {name: "id", type: "int"},
            {name: "myField", type: "string"},
            ...
        ]

        // This one is for our own usage, see bellow
        ,columns: [
            {dataIndex: "id", text: "ID},
            {dataIndex: "myField", text: "My field"},
            ...
        ]
    }
}

如文档中所述,当数据模型发生变化时,您也需要更新您的组件.Sencha 提供了metachange.请注意,虽然记录在代理中,但此事件将由商店中继.

As noted in the doc, when the data model changes, you'll want to update your components as well. Sencha has provided the metachange for that. Notice that, while documented in the proxy, this event will be relayed by the store.

最后,要更新网格的列模型,您有 重新配置 方法.例如,您可以通过以下方式修改您的网格类,使其根据服务器响应自动重新配置:

Finally, to update the grid's column model, you have the reconfigure method. For example, you could modify your grid class in the following way to make it reconfigure itself automatically from the server response:

Ext.define('Base.GridPanel', {
    extend: 'Ext.grid.Panel'

    // ...

    // You can add your listener in initComponent, if you're
    // reluctant to extend a method docuemented as private...
    ,bindStore: function(store) {

        // unbind previously bind store, if any
        var previous = this.getStore();
        if (previous) {
            previous.un('metachange', this.onMetaChange, this);
        }

        // bind to the meta change event
        this.getStore().on('metachange', this.onMetaChange, this);

        this.callParent(arguments);
    }

    ,onMetaChange: function(store, meta) {
        var columns = meta.columns;
        if (columns) {
            this.reconfigure(null, columns);
        }
    }
});

更新

onMetaChange 方法在 metachange 事件被触发时被调用,因为我已经用这一行将它注册为侦听器:

The onMetaChange method is called when the metachange event is fired, because I have registered it as a listener with this line:

this.getStore().on('metachange', this.onMetaChange, this);

当代理在服务器响应中检测到一些元数据时,会触发事件本身.具体来说,当服务器响应中存在 metaData 属性(或您可能已配置为代理的 metaProperty 的任何名称)时,就会发生这种情况.

The event itself is fired when the proxy detects some meta data in the server response. Concretely, that happens when a metaData property (or whatever name you may have configured as the metaProperty of the proxy) exists in the server response.

侦听器被有效地传递给响应中的原始 metaData 对象,作为它的第二个参数(在我的示例中名为 meta).因此,您的服务器可以将您需要的任何信息放入其中(例如新的字段标签、工具提示文本等).

The listener is effectively passed the raw metaData object, that is present in the response, as its second argument (named meta in my example). So your server can put any information you need in it (e.g. new field labels, tooltip texts, etc.).

bindStore 是一种已经存在于 GridPanel 中的方法.在这里我覆盖它,因为我需要一个地方来在商店中注册我的事件侦听器.顾名思义,调用此方法将存储绑定到组件.它可以是最初的商店,也可以是新的商店.这是我更喜欢覆盖此方法而不是 initComponent 的方法.如果存储在组件生命周期的后期发生变化,我的自定义侦听器将从旧存储中解除绑定并附加到新存储中.

bindStore is a method that is already present in GridPanel. Here I override it because I need a place to register my event listener on the store. As its name suggests, this method is called to bind a store to the component. It can be the initial store, or a new one. That's one I've preferred to override this method instead of initComponent. In case the store is changed later in the component life, my custom listener will be unbound from the old store and attached to the new one.

参数 关键字是 Javascript 的一个特性.它表示已传递给函数的所有参数.callParent 是 Ext 提供的用于调用父方法的甜食;它需要一个数组作为将传递给父级的参数.所以 this.callParent(arguments) 调用父方法而不必知道被覆盖方法的所有参数到底是什么.如果方法的参数发生变化,那会更容易,而且对未来的变化也更有弹性......

The arguments keyword is an idiosyncrasy of Javascript. It represents all the arguments that have been passed to a function. callParent is a sweety provided by Ext to call the parent method; it takes an array as the arguments that will be passed to the parent. So this.callParent(arguments) calls the parent method without having to know what were precisely all the arguments of the overridden method. That's easier, and that's also more resilient to future changes, if the arguments of the method were to change...

我很高兴为您提供有关在 Ext 中进行覆盖的综合指南...不幸的是,我无法通过快速搜索找到一个 :-/

I'd be glad to point you to a comprehensive guide about overriding in Ext... Unfortunately I couldn't find one with a quick search :-/

这篇关于从服务器端动态检索 GridPanel 模型/存储/列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆