【问题标题】:Retrieve GridPanel model/store/columns dynamically from server side从服务器端动态检索 GridPanel 模型/存储/列
【发布时间】:2013-09-12 16:19:30
【问题描述】:

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

我的问题是如何将值(字符串或 JSON)从服务器传递到 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 与以下模型一起使用并存储。

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 的方式:

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)

【问题讨论】:

    标签: c# extjs extjs4


    【解决方案1】:

    Ext 对此提供了一些支持。您可以通过将metaData 属性添加到服务器响应来发送模型配置。您可以使用metaProperty 选项配置属性的名称。

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

    {
        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。请注意,虽然记录在代理中,但此事件将由商店中继。

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

    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 事件被触发时被调用,因为我已经用这一行将它注册为监听器:

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

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

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

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

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

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

    【讨论】:

    • 嗨,这是一个很好的答案,非常感谢。你能为我澄清几点吗?如何/在哪里调用 onMetaChange?方法中的元参数是什么?它应该是服务器响应吗?你能添加一个小例子来说明它是如何一起工作的吗?非常感谢,我是一名新开发人员,仍在努力解决问题:)
    • 另外,我应该如何使用 bindStore() 以及 callParent() 中的 arguments 参数是什么?
    • 一般来说,这是有道理的,但我不知道如何使它工作。
    • 我已经更新了我的答案,试图澄清你提出的观点。但是为了让它工作,你应该(1)在你的服务器响应中添加一个metaData属性,可能是fieldscolumns,就像我的例子一样。然后(2)将bindStoreonMetaChange这两个方法复制粘贴到你自己的Base.GridPanel定义中。并且 (3) 在 onMetaChange 方法中放置一个 debugger 关键字。在那里您将能够检查您可用的内容(应该是商店和网格本身,即this 范围)。这应该会让你走得很远,然后你可以用你自己的案例来详细说明。
    • @PoonamBhatt metaProperty 选项允许您在服务器响应中为元数据使用另一个键名。例如,您可以将metaProperty 设置为'myMeta',并在您的回复中使用此名称而不是metaData。这是可选的,如果可以避免,我建议不要更改它。
    猜你喜欢
    • 1970-01-01
    • 2021-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-07
    • 1970-01-01
    • 2016-11-04
    相关资源
    最近更新 更多