3

我尝试了这种不同的方法,但仍然无法让过滤器工作。我的 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 不是函数

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

4

2 回答 2

4

除了 dbrin's 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;
            }
        });

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

于 2012-11-15T07:44:15.820 回答
1

我看到 2 个问题

  1. 商店应该remoteFilter: true设置

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

于 2012-11-15T04:57:24.470 回答