首页 > 解决方案 > 如何在 ExtJS6 中使用本地(内存)存储将过滤器功能应用于分页网格?

问题描述

我有一个带有本地商店的分页网格,我想使用我自己的函数应用过滤器。但它失败了。

从我使用的互联网推荐remoteFilter: trueenablePaging: true商店配置中的选项。

如果我使用特定的配置对象过滤存储,它会完美运行:

store.filter([{ property: 'age', value: 12 }]);

不幸的是,仅仅建立复杂的过滤标准是不够的。

根据文档,存储对象中有一种特殊filterBy方法可以将函数用作过滤器。但是,当我像这样提供它时:

store.filterBy( function( record ) {
  return record.get( 'age' ) <= 12;
});

我有一个错误Uncaught Error: Unable to use a filtering function in conjunction with remote filtering.

这是我在小提琴https://fiddle.sencha.com/#fiddle/2u8l中的工作示例

这是我的商店配置和来自控制器的所有业务逻辑。我将在此处跳过视图配置以专注于代码的主要部分(IMO)

Ext.define('TestGridViewModelr', {
    extend: 'Ext.app.ViewModel',

    alias: 'viewmodel.myexmpl.main.testgrid',

    data: {
    },
    formulas: {},
    stores: {
        simpsons: {
            model: 'Ext.data.Model',// 'SimpsonModel',
            pageSize: 2,
            // remoteSort: true,
            remoteFilter: true,
            proxy: {
                type: 'memory',
                enablePaging: true,
                reader: {
                    type: 'json',
                    rootProperty: 'items'
                }
            }
        }
    }

});

Ext.define('TestGridController', {
    extend: 'Ext.app.ViewController',

    alias: 'controller.myexmpl.main.testgrid',

    init: function () {
        console.log('controller inititalized\n  init async store loading...');
        setTimeout( this.onStoreLoad.bind( this ), 1000 );
    },

    initViewModel: function(vm){
        console.log( 'viewModel init', vm.get('test') );
    },
    emptyMethod: function () {},

    onStoreLoad: function () {
        console.log('loading store');
        var vm = this.getViewModel();
        var store = vm.getStore('simpsons');
        store.getProxy().data = this.getSimpsonsData().items;
        store.reload();
        // store.loadData( this.getSimpsonsData() );
    },

   //++++++++++++  FILTERING  ++++++++
    /* NO PROBLEM */
    onToggleFilter: function () {
        console.log('simple filter');
        var filter = this.getSimpleFilter()
        this.toggleFilter( filter );
    },
    /* PROBLEM */
    onToggleFnFilter: function(){
       console.log('function filter');
    //   var filterFn = this.filterChildren;
       var filterFn = this.getFilterUtil()
       this.toggleFilter( filterFn );
    },

    /* NO PROBLEM */
    getSimpleFilter: function(){
        return {
            property: 'age',
            value: '12'
        };
    },

    /* PROBLEM */
    getFilterUtil: function() {
        return Ext.create( 'Ext.util.Filter', {
            filterFn: this.filterChildren
        })
    },

    filterChildren: function( record ) {
        var age = record.get( 'age' );
        console.log( 'filter record up to age:', age )// debugger;
        return parseInt( age ) <= 12;
    },

    toggleFilter: function( fltr ) {
        var store = this.getViewModel().getStore( 'simpsons' );
        var filters = store.getFilters();
        if ( filters.length > 0 ) {
            store.clearFilter();
        } else {
           this. applyFilterToStore( fltr, store );
        }
    },

    applyFilterToStore: function( filter, store ){
        var method = Ext.isFunction( filter ) || filter instanceof Ext.util.Filter
            ? 'filterBy'
            : 'setFilters';
        store[method]( filter );
    },



    getSimpsonsData: function(){
        return  {
            'items': [{
                'name': 'Lisa',
                'age': 12,
                "email": "lisa@simpsons.com",
                "phone": "555-111-1224"
            }, {
                'name': 'Bart',
                'age': 8,
                "email": "bart@simpsons.com",
                "phone": "555-222-1234"
            }, {
                'name': 'Homer',
                'age': 40,
                "email": "homer@simpsons.com",
                "phone": "555-222-1244"
            }, {
                'name': 'Marge',
                'age': 34,
                "email": "marge@simpsons.com",
                "phone": "555-222-1254"
            }]
        }
    }
});



一般来说,我希望能够以编程方式在带有本地商店的分页网格上设置过滤条件。函数允许我扩展过滤功能并使用连词和查​​询构建灵活的逻辑表达式。例如:

name.lenght <= 4 &&  ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)

提前谢谢你,A。

标签: extjsfiltergridlocalpaging

解决方案


您不能在一家商店中remoteFilter同时使用两者。filterBy决定过滤器的逻辑应该是打开Client Side还是Server Side

如果 on server side,设置remoteFilterastrue并使用filter带有额外参数的操作,您可以在服务器上捕获并执行过滤器。

如果 on client side,设置remoteFilterasfalse并使用filterBy您附加的功能。

检查小提琴上的例子(我只是改变了一些东西):https ://fiddle.sencha.com/#fiddle/2ua4&view/editor


推荐阅读