【问题标题】:Filter store on combobox selection在组合框选择上过滤存储
【发布时间】:2012-11-03 03:14:20
【问题描述】:

我尝试了不同的方法,但仍然无法让过滤器工作。我的 ext 应用程序允许用户从组合框中选择单个状态,下面的网格显示有关所选“值”=状态的更多数据。在选择时,组合框会触发一个过滤网格存储并更新存储的函数... 这是我的网格商店...

var store = Ext.create('Ext.data.Store', {
        autoLoad: true,
        id: 'OurData',
        pageSize: 20,
        pageNumber: 1,
        remoteSort: true,
        fields: [
    { name: 'States' },
    { name: 'FullName' },
    { name: 'Capital' },
    { name: 'Population' }
    ],
        proxy: {
            type: 'ajax',
            url: 'GetState/getS',
            reader: {
                type: 'json',
                root: 'myTable',
               idProperty: 'States',
                totalProperty: '@count'
            }
        }
    });
    store.loadPage(1);

这是我的组合框

xtype: 'combo',
                    id: 'iccombo',
                    scope: this,
                    store: this.Combostore,
                    fieldLabel: 'Short State',
                    displayField: 'States',
                    valueField: 'States',
                    typeAhead: true,
                    triggerAction: 'all',
                    queryMode: 'remote',
                    name: 'State',
                    labelWidth: 125,
                    anchor: '95%',
                    listeners: {
                        scope: this,
                        select: this.fireFilter
                    }

这就是过滤器应该发生的地方......

fireFilter: function (value) {

    // Get passed value
    this.selectedC = value.getValue();
    console.log('selectedValue: ' + this.selectedC);

    // Clear existing filters
    this.store.clearFilter(false);

    // Build filter

    var myfilter = Ext.create('Ext.util.Filter', {
        scope: this,
        filterFn: function (item) {
            var fieldNames = item.fields.keys;

            for (var j = 0; j < fieldNames.length; j++) {
                var fieldName = fieldNames[j];
                if (item.data[fieldName] != null) {
                    var stringVal = item.data[fieldName].toString();
                    if (stringVal != null && stringVal.toLowerCase().indexOf(value.toLowerCase()) != -1) {
                        return true;
                    }
                }
            }
            return false;
        }

    });
    // Apply filter to store
    this.store.filter(myfilter);
}

当我运行代码时,它会在网格中显示所有数据,并且在选择组合框时,它仍然显示相同的数据.. 出于某种原因,代码永远不会通过 filterFn... 因为我的 console.log 没有出现 这是我在萤火虫的回应中得到的

_dc     1352902173425
filter  [{"property":null,"value":null}]
limit   20
page    1
start   0

您可以清楚地看到,选择的“值”为空,但我的“console.log”打印选择的值...我认为我获取传递值和应用过滤器的方式不正确...有人可以看看...谢谢

更新...我能够进入函数内部,并且我的 console.log 显示所有字段...但是一旦我到达最后一个 if 语句...我收到此错误

TypeError: value.toLowerCase 不是函数

我在这里做错了什么?谢谢

【问题讨论】:

    标签: extjs combobox grid extjs4 extjs4.1


    【解决方案1】:

    除了 dbrin 的 anwser 我也无法理解你为什么使用remoteSort 而不是remoteFilter?使用this 可能还会遇到范围问题。

    无论如何,我建议您扩展一个新的组合类型,这样您也可以在需要时清除您的过滤器。这是我为自己使用而编写的扩展。注意过滤本身需要在onSearch方法中实现,可以是远程排序也可以是本地排序。

    Ext.define('Ext.ux.form.field.FilterCombo', {
        extend: 'Ext.form.field.ComboBox',
        alias: 'widget.filtercombo',
        /**
        * @cfg {string} recordField
        * @required
        * The fieldname of the record that contains the filtervalue
        */
    
        /**
        * @cfg {string} searchField
        * @required
        * The fieldname on which the filter should be applied
        */
    
        /**
        * @cfg {boolean} clearable
        * Indicates if the clear trigger should be hidden. Defaults to <tt>true</tt>.
        */
        clearable: true,
    
        initComponent: function () {
            var me = this;
    
            if (me.clearable)
                me.trigger2Cls = 'x-form-clear-trigger';
            else
                delete me.onTrigger2Click;
    
            me.addEvents(
    
                /**
                * @event clear
                *
                * @param {Ext.ux.form.field.FilterCombo} FilterCombo The filtercombo that triggered the event
                */
                'clear',
                /**
                * @event beforefilter
                *
                * @param {Ext.ux.form.field.FilterCombo} FilterCombo The filtercombo that triggered the event
                * @param {String/Number/Boolean/Float/Date} value The value to filter by
                * @param {string} field The field to filter on
                */
                'beforefilter'
            );
    
            me.callParent(arguments);
            // fetch the id the save way
            var ident = me.getId();
    
            me.on('select', function (me, rec) {
                var value = rec[0].data[me.recordField],
                    field = me.searchField;
                me.fireEvent('beforefilter', me, value, field)
                me.onShowClearTrigger(true); 
                me.onSearch(value, field);
            }, me);
            me.on('afterrender', function () { me.onShowClearTrigger(); }, me);
        },
    
        /**
        * @abstract onSearch
        * running a search on the store that may be removed separately
        * @param {String/Number/Boolean/Float/Date} val The value to search for
        * @param {String} field The name of the Field to search on
        */
        onSearch: Ext.emptyFn,
    
        /**
        * @abstract onFilterRemove
        * removing filters from the the
        * @param {Boolean} silent Identifies if the filter should be removed without reloading the store
        */
        onClear: Ext.emptyFn,
    
        onShowClearTrigger: function (show) {
            var me = this;
            if (!me.clearable)
                return;
            show = (Ext.isBoolean(show)) ? show : false;
            if (show) {
                me.triggerEl.each(function (el, c, i) {
                    if (i === 1) {
                        el.setWidth(el.originWidth, false);
                        el.setVisible(true);
                        me.active = true;
                    }
                });
            } else {
                me.triggerEl.each(function (el, c, i) {
                    if (i === 1) {
                        el.originWidth = el.getWidth();
                        el.setWidth(0, false);
                        el.setVisible(false);
                        me.active = false;
                    }
                });
            }
            // Version specific methods
            if (Ext.lastRegisteredVersion.shortVersion > 407) {
                me.updateLayout();
            } else {
                me.updateEditState();
            }
        },
    
        /**
        * @override onTrigger2Click
        * eventhandler
        */
        onTrigger2Click: function (args) {
            this.clear();
        },
    
        /**
        * @private clear
        * clears the current search
        */
        clear: function () {
            var me = this;
            if (!me.clearable)
                return;
            me.onClear(false);
            me.clearValue();
            me.onShowClearTrigger(false);
            me.fireEvent('clear', me);
        }
    });
    

    这是您的组合的未经测试的实现。请注意,我清理了你的filterFn,但我没有做任何进一步的检查。

    {
        xtype: 'filtercombo',
        id: 'iccombo',
        scope: this,
        store: this.Combostore,
        fieldLabel: 'Short State',
        displayField: 'States',
        valueField: 'States',   
        typeAhead: true,
        triggerAction: 'all',
        queryMode: 'remote',
        name: 'State',
        labelWidth: 125,
        anchor: '95%',
        // begin new parts
        recordField: 'States',
        searchField: '',
        clearable: false,
        onSearch: function (me, value, field) {
    
            // New part!
            var store = Ext.StoreMgr.lookup('YourStoreIdName');
    
            // Clear existing filters
            store.clearFilter(false);
    
            // Build filter
            var myfilter = Ext.create('Ext.util.Filter', {
            scope: this,
            filterFn: function (item) {
                var fieldNames = item.fields.keys,
                    fieldName, stringVal,
                    len = fieldNames.length,
                    j = 0;
    
                for (; j < len; j++) {
                    fieldName = fieldNames[j];
                    if (item.data[fieldName] != null) {
                        stringVal = item.data[fieldName].toString();
                        if (stringVal != null && stringVal.toLowerCase().indexOf(value.toLowerCase()) != -1) {
                            return true;
                        }
                    }
                }
                return false;
            }
        });
            // Apply filter to store
            store.filter(myfilter);
        }
    }
    

    我想这也应该有效

    var myfilter = Ext.create('Ext.util.Filter', {
                scope: this,
                filterFn: function (rec) {
                    var fieldValue = rec[this.fieldName];
                    if (fieldValue && fieldValue === this.value)
                          return true;
                return false;
                }
            });
    

    我在两个 var 之前设置了 this 以将它们标记为来自外部范围。

    【讨论】:

    • 感谢您提供详细信息...已使用范围:这是我已将我的商店声明为 this.myStore...
    • 谢谢 sra... 我希望他们不是拼写错误.. :)... for 循环是否缺少声明?
    • 我实际上可以进入 filterFn 但什么也没有发生...没有错误但空白网格..我注意到的是...我的控制台打印说存储未定义...我有一种感觉所选值未正确传递
    • 是的...我将其更改为与我的商店名称匹配...我还检查了是否正在传递值并打印所选值... this.selectedC = value.getValue ();... console.log('selectedValue: ' + this.selectedC);... 我在返回 false 时也做了一个 consoleprint... 它打印的是 false..
    • M 几乎就在那里...我到了搜索 if 语句的最后一部分...TypeError: value.toLowerCase is not a function
    【解决方案2】:

    我看到了 2 个问题

    1. 商店应该设置remoteFilter: true

    2. 在 JavaScript 中,所有变量声明都被挑选出来并提升到函数的开头。所以在循环中声明的任何变量都应该被取出并在函数的顶部声明。 JS 没有块作用域(如 Java)。

    【讨论】:

    • 感谢您的指点 dbrin...我尝试了 remoteFilter,但当时它仍然无法正常工作...肯定会全局声明我的变量
    • 不不,不是全球性的!你想在函数的顶部声明你的变量(函数作用域!)——这样你就可以避免循环中的错误。请记住,变量在循环结束后仍然存在 - 不像 Java 中那样。
    • oooooh ok...这就是您所说的...是的...实际上在 sra 的帮助下,我能够做到这一点...谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-11
    • 2018-08-10
    • 1970-01-01
    相关资源
    最近更新 更多