2017-06-19 45 views
3

我有一个配置了memory proxyenablePaging: true的商店。商店的remoteFilterremoteSort设置为true,以便过滤和排序由代理处理的请求。ExtJS 6在内存代理中使用自定义过滤功能

当我通过多个字段过滤我的商店时,我想使用OR条件,而不是AND。

没有记忆代理分页,我可以用remoteFilter: false和自定义过滤功能,如:

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

但我怎么能启用分页实现这一目标?覆盖内存代理?

回答

2

Ext.data.proxy.Memory.read使用Ext.util.Filter.createFilterFn基于传递Ext.util.Filter [](带有属性值CONFIGS)创建过滤器功能覆盖memroy代理阅读方法和使用自定义函数来创建过滤器功能:

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

     ... 

     } 
    } 
}); 
0

您可以覆盖内存代理以满足您的需求,或者,如果您只希望在searchFields中指定的字段之一中查找字符串,则可以使用指定的convert方法向模型添加“虚拟”字段。

例如:

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

所有你需要在店里做的就是:

store.filter('searchField', searchText); 

这不正是你所寻找的东西,但它应该完成这项工作。

// 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); 
} 

所以,如果你想使用不同的过滤逻辑,您可以:

+0

感谢的想法,但我有很多数据,我认为〜加倍它可能会影响性能(也许我错了,病检查)所以我试图找到一个不同的解决方案。看起来我没有别的选择,只能覆盖代理并使用第二个存储。 –

+0

是的,这并不理想。对于大部分数据,我建议创建一个自定义代理。 – MarthyM