Ext JS网格排序作为字符串而不是JSON发送

Ext JS grid sort sent as a String instead of JSON

本文关键字:JSON 发送 字符串 JS 网格 排序 Ext      更新时间:2023-09-26

我正在尝试用Sencha Ext JS实现服务器端排序,并注意到一些奇怪的事情。JSON的分页部分看起来很好,但是sort属性被设置为String而不是Array:

实际:

{"page":1,"start":0,"limit":50,"sort":"[{'"property'":'"firstName'",'"direction'":'"ASC'"}]"}
预期:

{"page":1,"start":0,"limit":50,"sort":[{"property":"firstName","direction":"ASC"}]}

ExtJs代码:

Ext.require([
    'Ext.grid.*',
    'Ext.data.*',
    'Ext.panel.*',
    'Ext.layout.container.Border'
]);
Ext.define('Customer',{
    extend: 'Ext.data.Model',
    fields: [
      {name: 'id',        type: 'int'},
      {name: 'firstName', type: 'string'},
      {name: 'lastName',  type: 'string'},
      {name: 'companyName',  type: 'string'}
    ]
});
Ext.onReady(function(){
    var itemsPerPage = 50; // Paging
    var store = Ext.create('Ext.data.Store', {
        pageSize: itemsPerPage,
        // autoLoad: true,
        autoLoad: {start: 0, limit: itemsPerPage},
        autoSync: true, 
        model: 'Customer',
        remoteSort: true,
        proxy: {
            paramsAsJson: true,
            actionMethods: {
                read: 'POST'
            },
            type: 'rest', // was... 'ajax',
            url: '/customers',
            reader: {
                type: 'json',
                root: 'content',
                totalProperty: 'totalElements'
            },
            writer: {
                type: 'json'
            },
            listeners: {
                write: function(store, operation){
                    var record = operation.getRecords()[0],
                        name = Ext.String.capitalize(operation.action),
                        verb;
                    if (name == 'Destroy') {
                        record = operation.records[0];
                        verb = 'Destroyed';
                    } else {
                        verb = name + 'd';
                    }
                    Ext.example.msg(name, Ext.String.format("{0} user: {1}", verb, record.getId()));
                }
            }            
        }
    });    
    var rowEditing = Ext.create('Ext.grid.plugin.RowEditing', {
        listeners: {
            cancelEdit: function(rowEditing, context) {
                // Canceling editing of a locally added, unsaved record: remove it
                if (context.record.phantom) {
                    store.remove(context.record);
                }
            }
        }
    });    
    // create the grid
    var grid = Ext.create('Ext.grid.Panel', {
        bufferedRenderer: false,
        store: store,
        columns: [
            {text: "ID", width: 120, dataIndex: 'id', sortable: true},
            {text: "First Name", flex: 1, dataIndex: 'firstName', sortable: true, editor: 'textfield'},
            {text: "Last Name", width: 125, dataIndex: 'lastName', sortable: true, editor: 'textfield'},
            {text: "Company Name", width: 125, dataIndex: 'companyName', sortable: true}
        ],
        forceFit: true,
        height:210,
        split: true,
        region: 'north',
        plugins: [rowEditing],
        // Paging
        dockedItems: [{
            xtype: 'pagingtoolbar',
            store: store,   // same store GridPanel is using
            dock: 'bottom',
            displayInfo: true
        }],
    });    
    // define a template to use for the detail view
    var customerTplMarkup = [
        'ID: {id}<br/>',
        'First Name: {firstName}<br/>',
        'Last Name: {lastName}<br/>',
        'Company Name: {companyName}<br/>'
    ];
    var customerTpl = Ext.create('Ext.Template', customerTplMarkup);    
    Ext.create('Ext.Panel', {
        renderTo: 'binding-example',
        frame: true,
        title: 'Customer List',
        width: 580,
        height: 400,
        layout: 'border',
        items: [
            grid, {
                id: 'detailPanel',
                region: 'center',
                bodyPadding: 7,
                bodyStyle: "background: #ffffff;",
                html: 'Please select a customer to see additional details.'
        }]
    });    
    // update panel body on selection change
    grid.getSelectionModel().on('selectionchange', function(sm, selectedRecord) {
        if (selectedRecord.length) {
            var detailPanel = Ext.getCmp('detailPanel');
            detailPanel.update(customerTpl.apply(selectedRecord[0].data));
        }
    });    
});

i添加了beforeload侦听器到存储

下面是一个工作示例:

listeners: {
        beforeload: function(store, operation, eOpts){
            var sort = [];
            var filter = [];
            if(operation._sorters){
                for(var i = 0; i< operation._sorters.length; i++){
                    var direction = operation._sorters[i]._direction;
                    var property = operation._sorters[i]._property;
                    sort.push({ 
                        "direction" : direction,
                        "property"  : property
                    });
                }
                operation._proxy.extraParams = {sort:sort};
            }
            if(operation._filters){
                for(var i = 0; i< operation._filters.length; i++){
                    var operator = operation._filters[i]._operator;
                    var property = operation._filters[i]._property;
                    var value = operation._filters[i]._value;
                    filter.push({ 
                        "operator" : operator,
                        "property"  : property,
                        "value"  : value
                    });
                }
                operation._proxy.extraParams = {filter:filter};
            }
        }
    }