ExtJS 6 Use custom filter function within memory proxy

纵然是瞬间 提交于 2019-12-10 18:07:33

问题


I have a store configured with memory proxy with enablePaging: true. Store's remoteFilter and remoteSort set to true so filtering and sorting requests handled by proxy.

When I filter my store by multiple fields I want to use OR condition, not AND.

Without memory proxy paging I could use remoteFilter: false and custom filter function like:

store.filterBy(function (record)
{
    for (var i = 0; i < searchFields.length; ++i) {
        if (record.get(searchFields[i]).toLowerCase().indexOf(searchText) !== -1) {
            return true;
        }
    }
    return false;
});

But how I can achieve this with enabled paging? Override memory proxy?


回答1:


Ext.data.proxy.Memory.read use Ext.util.Filter.createFilterFn to create a filter function based on passed Ext.util.Filter[] (with property-value configs):

// Filter the resulting array of records 
if (filters && filters.length) {
    // Total will be updated by setting records 
    resultSet.setRecords(records = Ext.Array.filter(records, Ext.util.Filter.createFilterFn(filters)));
    resultSet.setTotal(records.length);
}

So, if you want to use different filter logic, you can override memroy proxy read method and use custom function to create filter function:

Ext.define('MyApp.extensions.FilterMemoryProxy', {
    extend: 'Ext.data.proxy.Memory',
    alias: 'proxy.filtermemory',

    createCustomFilterFn: function (filters)
    {
        if (!filters) {
            return Ext.returnTrue;
        }
        return function (candidate)
        {
            var items = filters.isCollection ? filters.items : filters,
                length = items.length,
                i, filter;
            for (i = 0; i < length; i++) {
                filter = items[i];
                if (!filter.getDisabled() && candidate.get(filter.getProperty()).toLowerCase().indexOf(
                        filter.getValue().toLowerCase()) !== -1) {
                    return true;
                }
            }
            return false;
        };
    },

    read: function (operation)
    {

        ...

        if (operation.process(resultSet, null, null, false) !== false) {
            // Filter the resulting array of records
            if (filters && filters.length) {
                // Total will be updated by setting records
                resultSet.setRecords(records = Ext.Array.filter(records, me.createCustomFilterFn(filters)));
                resultSet.setTotal(records.length);
            }

        ...

        }
    }
});



回答2:


You can override the memory proxy to suit your needs, or, if you only wish to find a string in one of the fields specified in searchFields, you can add a 'virtual' field to the model with the convert method specified.

For example:

// Extend Ext.data.Model or create it. Dealer's choice.
Ext.define('MyLocalModel', {
    extend: 'Ext.data.model',
    fields: [
        ...
        {
            name: 'searchField',
            type: 'string',
            convert: function(value, record) {
                // Get search fields somewhere
                var resultArray = [];
                for (var i = 0; i < searchFields.length; ++i) {
                    var searchField = searchFields[i];
                    var fieldValue = record.get(searchField);
                    resultArray.push(fieldValue);
                }

                // Join by a string that would not normally be searched
                // so that field values 'foo' and 'bar' are not valid when searching 'ooba'
                var result = resultArray.join('**');
                return result;
            }
        }
    ]
});

All you need to do in the store then is:

store.filter('searchField', searchText);

It's not exactly what you are searching for, but it should get the job done.



来源:https://stackoverflow.com/questions/44621597/extjs-6-use-custom-filter-function-within-memory-proxy

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!