EXTJS 4 - 网格过滤器或商店过滤器清除商店现有的过滤器

Posted

技术标签:

【中文标题】EXTJS 4 - 网格过滤器或商店过滤器清除商店现有的过滤器【英文标题】:EXTJS 4 - Grid Filter or store filter clearing existing filter on store 【发布时间】:2015-02-18 08:00:43 【问题描述】:

我遇到了一个问题,即网格过滤器正在清除商店中的现有过滤器。

基本上,我有两个相互重叠的网格,当用户单击顶部网格时,数据被过滤到第二个网格中,这是发生问题的第二个网格。

我通过小提琴创建了一个简化的问题示例

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

备注

需要注意的是,我正在通过 record.beginEdit() 命令“展平”嵌套的 JSON 自定义字段,以便可以在网格中显示这些数据。我正在使用remoteFilter: false,如果将其设置为remoteFilter: true,则过滤器部分有效,但remoteFilter: true 通过record.beginEdit(); 破坏嵌套数据集

如何重现

1) 如果您在Name 列中应用上面的网格过滤器并选择Homer,那么网格过滤器将清除第 113 行中应用到商店的过滤器,现在显示两条 Homer 记录。有两个 Homer 记录,但每个都有不同的 summaryId 值。

store.filter([id: 'summaryId', property: 'summaryId', value:1, exactMatch: true]);

2) 如果取消选择过滤器,则不会保留第 113 行中应用于商店的过滤器,并且现在会显示所有记录。

【问题讨论】:

您的数据中有两个“本垒打”,虽然是不同的电子邮件 凯文,感谢您的回复。我更新了我的帖子,我的 JSON 中有两条 Homer 记录,它们都有不同的 summaryId 值,过滤器仅适用于 summaryId 1,但在网格过滤器中选择 Homer 会导致商店过滤器被删除。 如何获取日志以查看 Sencha Fiddle 上的重复项 我没有关注,你能澄清一下你的意思吗? 为什么不使用本地 false,而是在 FilterFeature 中使用本地过滤?那么,您可以动态过滤来自 url 的数据...?或者,您可以根据需要为“summaryId”列创建一个 Filterable? 【参考方案1】:

像下面这样更改您的商店:

store = Ext.create('Filter.data.Store', 
    data: data,
    filters: [
        property: 'summaryId',
        value: '1'
    ]
);

从您之前的演示中查看this 演示...

编辑: 试试这个代码到你的小提琴中,这是一种非常复杂的方法。所以,你需要一个触发器来像一个按钮一样过滤,这可能会给你一点帮助。我也编辑了我的演示,请查看。

/*global Ext:false */
Ext.Loader.setPath(

);

Ext.require(['*', 'Ext.ux.grid.FiltersFeature']);

Ext.define('Filter.data.Store', 
    extend: 'Ext.data.Store',
    id: 'simpsonsStore',
    autoLoad: true,
    remoteFilter: false,
    fields: [
        name: 'name'
    , 
        name: 'email'
    , 
        name: 'phone'
    , 
        name: 'summaryId'
    , 
        name: 'customFields'
    , 
        name: 'customFieldId129'
    , 
        name: 'customFieldId130'
    ],
    proxy: 
        type: 'memory',
        reader: 
            type: 'json',
            root: 'items'
        
    
);


Ext.onReady(function() 

    var filters = 
        ftype: 'filters',
        encode: false,
        local: true
    ;

    data = 
        "total": 5,
        "items": [
            'id': 1,
            'summaryId': 1,
            'name': 'Lisa',
            "email": "lisa@simpsons.com",
            "phone": "555-222-1234",
            "customFields": [
                "customFieldId": 129, // there can be multiple customfields
                "customFieldValue": "Bob"
            , 
                "customFieldId": 130, // there can be multiple customfields
                "customFieldValue": "Smith"
            , ]
        , 
            'id': 2,
            'summaryId': 1,
            'name': 'Bart',
            "email": "bart@simpsons.com",
            "phone": "555-222-1244",
            "customFields": []
        , 
            'id': 3,
            'summaryId': 1,
            'name': 'Homer',
            "email": "home@simpsons.com",
            "phone": "555-222-1244",
            "customFields": []
        , 
            'id': 4,
            'summaryId': 2,
            'name': 'Fred',
            "email": "fred@simpsons.com",
            "phone": "555-222-1264",
            "customFields": []
        , 
            'id': 5,
            'summaryId': 2,
            'name': 'Homer',
            "email": "HomerWork@simpsons.com",
            "phone": "555-222-1264",
            "customFields": []
        ]
    ,

    store = Ext.create('Filter.data.Store', 
        data: data,
        //filters: [
        //    property: 'summaryId',
        //    value: '1'
        //]
    );

    store.load(
        callback: function() 
            for (var i = 0; i < store.data.length; i++) 
                var record = store.getAt(i);
                var customFieldsData = record.data.customFields;
                if (customFieldsData.length > 0) 
                    for (var j = 0; j < customFieldsData.length; j++) 
                        record.beginEdit();
                        store.filter([property: 'summaryId',value: '1']);
                        record.set('customFieldId' + customFieldsData[j].customFieldId, customFieldsData[j].customFieldValue);
                        record.endEdit(true);
                    
                
                //store.sync();
            
        
    );

    // apply custom fields
    // the custom field code is an example, in short , nested data
    // and need to use the record function for each record so that the
    // grid can see the record


    //store.filter([property: 'summaryId',value: '1']);
    var btn = Ext.create('Ext.Button', 
        text: 'Click me For filter summaryId',
        renderTo: Ext.getBody(),
        handler: function() 
            if(store.isFiltered())
                //var data = Ext.encode(grid.filters.getFilterData());
                var data1 = grid.filters.getFilterData();
                store.filter([property: 'summaryId',value: '1']);
                store.filter([property: data1[0].field,value: data1[0].data.value]);
                //Ext.Msg.alert('All Filter Data',data1[0].field + " " + data1[0].data.value);
                //Ext.Msg.alert('All Filter Data',data);
            
        
    );

    var grid = Ext.create('Ext.grid.Panel', 
        xtype: 'gridpanel',
        title: 'filter is on summaryId 1 - Selecting Homer returns two records instead of one',
        store: store,
        features: [filters],
        columns: [
            header: 'Name',
            dataIndex: 'name',
            filter: 
                type: 'list',
                options: ['Homer']
            
        , 
            header: 'summaryId',
            dataIndex: 'summaryId'
        , 
            header: 'customField1',
            dataIndex: 'customFieldId129' //hardcoded for fiddler example
        , 
            header: 'customField2',
            dataIndex: 'customFieldId130' //hardcoded for fiddler example
        ],
        width: 700,
        height: 500,
        renderTo: Ext.getBody()
    );
);

【讨论】:

谢谢...这确实有效,但是对于我的真实应用程序,我有两个相互重叠的网格,当用户单击顶部网格时,数据将被过滤到第二个网格中。假设用户返回并单击顶部网格上的不同行,我如何确保我可以更改过滤器值而无需重新加载商店并再次执行 record.beginEdit()... 如果你想创建一个主从网格,需要顶部网格的过滤参数传递到你的第二个网格,你需要使用存储方法。但后果是你的问题是这样的。我建议您使用 local:false (使用 ajax 过滤以指出您的需要)而不是使用 Loca:true 过滤...... Eko,如果我清楚地理解你,你是在建议我让服务器过滤数据并发送回客户端......对不起所有愚蠢的问题。 是的,抱歉我的英语不好...所以您只需从以前的过滤器中获取商店数据。 Eko,你没有什么可道歉的:)...谢谢您的输入...如果有某种方法可以将数据保留在 record.beginEdit() 中,我的问题将得到解决,那么我可以使用 remoteFilter:true。

以上是关于EXTJS 4 - 网格过滤器或商店过滤器清除商店现有的过滤器的主要内容,如果未能解决你的问题,请参考以下文章

ExtJS:: 如何过滤网格中的行,但不在存储中

如何在每个组 ExtJS 4 中过滤分组网格

ExtJS 2.3/3.x 网格存储

ExtJS 网格过滤器:如何从外部 json 加载“列表”过滤器选项?

extjs 5 商店同步绑定到选择 hasMany

即使在过滤时重新加载商店后网格也不会改变