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

コードを実行すると、グリッド内のすべてのデータが表示され、コンボボックスを選択しても同じデータが表示されます。何らかの理由で、console.logが実行されないため、コードがfilterFnを通過することはありません。これは私がfirebugの応答で得たものです

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

ご覧のとおり、選択した「値」はnullですが、「console.log」は選択した値を出力します...渡された値を取得してフィルターを適用する方法が間違っていると思います...誰かお願いします見てください...ありがとう

更新...関数内に入ることができ、console.logにすべてのフィールドが表示されます...しかし、最後のifステートメントに到達すると...このエラーが発生します

TypeError:value.toLowerCaseは関数ではありません

私はここで何が間違っているのですか?ありがとう

4

2 に答える 2

4

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

2つの変数の前に設定thisして、外部スコープからのものとしてマークします。

于 2012-11-15T07:44:15.820 に答える
1

2つの問題があります

  1. ストアがremoteFilter: true設定されている必要があります

  2. JavaScriptでは、すべての変数宣言が選択され、関数の先頭に引き上げられます。したがって、ループ内で宣言された変数はすべて取り出して、関数の先頭で宣言する必要があります。JSにはブロックスコープがありません(Javaのように)。

于 2012-11-15T04:57:24.470 に答える