如何将过滤器功能应用于ExtJS6中具有本地(内存)存储的分页网格? [英] How to apply filter function to paging grid with local(memory) store in ExtJS6?

查看:87
本文介绍了如何将过滤器功能应用于ExtJS6中具有本地(内存)存储的分页网格?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有本地存储的分页网格,并且我想使用自己的函数来应用过滤器.但这是失败的.

I have a paging grid with local store, and I want to apply a filter using my own function. But it is failed.

在互联网推荐中,我在商店配置中使用了 remoteFilter:true enablePaging:true 选项.

From internet recommendations I used remoteFilter: true and enablePaging: true options in store config.

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

And it works perfectly if I filter store with specific configuration object:

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

不幸的是,建立复杂的过滤条件还不够.

unfortunately it is not enough to build complex filter criteria.

符合文档存储对象中有一个特殊的 filterBy 方法,可以将函数用作过滤器.但是,当我以这种方式提供它时:

In accordance with documentation there is a special filterBy method in store object to use function as filter. But, when I am providing it like this:

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

我遇到错误未捕获的错误:无法将过滤功能与远程过滤结合使用.

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

Here is my working example in fiddle https://fiddle.sencha.com/#fiddle/2u8l

这是我的商店配置以及控制器中的所有业务逻辑.我将在这里跳过视图配置,重点关注代码的主要部分(IMO)

This is my store configuration and all business logic from controller. I'll skip view configuration here to focus on main part( IMO )of code

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"
            }]
        }
    }
});



通常,我希望能够以编程方式在本地商店的分页网格上设置过滤条件.函数使我能够扩展过滤器功能,并使用合取和分配来构建灵活的逻辑表达式.例如:

In general I want to have ability to set up filter criteria on paging grid with local store programmatically. Function allows me to extend filter capabilities and build flexible logical expression using conjunction and disquisition. For example:

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

预先感谢您,答:

推荐答案

我终于解决了这个问题!

I have finally resolved this issue!

在接下来的几行中,在商店的onFilterEndUpdate方法中引发了提及的错误:

Mentioned error raised in onFilterEndUpdate method of store in next lines:

...
me.getFilters().each(function(filter) {
  if (filter.getInitialConfig().filterFn) {
    Ext.raise('Unable to use a filtering function in conjunction with remote filtering.');
  }
});
...

我已经在我的商店实体中覆盖了此方法,并注释掉了这些行.我知道这不是最好的解决方案,但我找不到更好的解决方案.

I have override this method in my store entity and commented out these lines. I know it is not best solution, but I could not find better one.

这是有关此主题的完整解决方案:

Here is the complete solution concerning this topic:

  1. 使用 remoteFilter:true enablePaging:true 选项配置存储:
  1. Configure store with remoteFilter: true and enablePaging: true options:

{
 model: 'Ext.data.Model',
 pageSize: 2,
 remoteFilter: true,
 proxy: {
   type: 'memory',
   enablePaging: true,
   reader: {
     type: 'json'
   }
 }
}

  1. 使用其 Proxy 而不是 loadData 方法将数据加载到存储中:
  1. Load data into the store using its Proxy instead of loadData method:

store.getProxy().data = this.getSimpsonsData().items;
store.reload();

  1. 在商店初始化后重写onFilterEndUpdate方法,并注释掉提到的行,即:

onStoreLoad: function() {
...
  store.onFilterEndUpdate = this.onFilterEndUpdate.bind( store );
...
},

onFilterEndUpdate: function() {
  var me = this
    , suppressNext = me.suppressNextFilter
    , filters = me.getFilters(false);
  // If the collection is not instantiated yet, it's because we are constructing.
  if (!filters) {
    return;
  }
  if (me.getRemoteFilter()) {
    // me.getFilters().each(function(filter) {
    //      if (filter.getInitialConfig().filterFn) {
    //          Ext.raise('Unable to use a filtering function in conjunction with remote filtering.');
    //      }
    // });
    me.currentPage = 1;
    if (!suppressNext) {
      me.load();
    }
  } else if (!suppressNext) {
    me.fireEvent('datachanged', me);
    me.fireEvent('refresh', me);
  }
  if (me.trackStateChanges) {
    // We just mutated the filter collection so let's save stateful filters from this point forward.
    me.saveStatefulFilters = true;
  }
  // This is not affected by suppressEvent.
  me.fireEvent('filterchange', me, me.getFilters().getRange());
}

以下是提琴演奏中的实时示例 https://fiddle.sencha.com/#fiddle/2ub7

Here is live example in fiddle https://fiddle.sencha.com/#fiddle/2ub7

这篇关于如何将过滤器功能应用于ExtJS6中具有本地(内存)存储的分页网格?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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