Ext.js の Search-As-You-Type コンポーネントに取り組んでいます。複数の単語を AND フィルタリングする機能があり、それぞれがレコードのプロパティに対して OR フィルタリングでチェーンされています。その後。「Ke Ba」と入力すると、「Kevin Bacon」と「Becky Kennedy」がフィルターされます。
初期データセットをリモート モードで読み込んでいます。
何が起こるかというと、REST-Proxy と JSON Reader を介してデータがストアにロードされます。現在、サーバー側で「フィルタリング」するのではなく、データセットがサーバーからフィルタリングされたかのように、すべてを返し、クライアントでフィルターをモックします。コンボボックスのようです。
検索文字列を「Kre Ba」に変更すると、REST-API (すべてのデータ) から再読み込みされますが、「Kre Ba」に一致するレコードがないため、Store はコンボボックスに空になります。 .
どういうわけか、Ext-js がコンボボックスの値をリセットすることを決定し、検索文字列全体が消えます。
フィルタリング後にストアに一致するアイテムがない場合でも、検索文字列を保持する適切な方法はありますか?!
値をリセットする Ext.js コードを次に示します。
 onLoad: function(store, records, success) {
    var me = this;
    if (me.ignoreSelection > 0) {
        --me.ignoreSelection;
    }
    // If not querying using the raw field value, we can set the value now we have data
    if (success && !store.lastOptions.rawQuery) {
        // Set the value on load
        // There's no value.
        if (me.value == null) {
            // Highlight the first item in the list if autoSelect: true
            if (me.store.getCount()) {
                me.doAutoSelect();
            } else {
                // assign whatever empty value we have to prevent change from firing
                me.setValue(me.value);
            }
        } else {
            me.setValue(me.value);
        }
    }
},
デバッグ中に、チェックのためにme.store.getCount()返されることがわかりました。false
アップデート:
ここに私のコンボボックスの設定があります:
Ext.define('MyApp.view.SearchAsYouTypeCombobox', {
extend: 'Ext.form.field.ComboBox',
alias: 'widget.SearchAsYouTypeCombobox',
fieldLabel: 'Label',
hideLabel: true,
emptyText: 'Search',
hideTrigger: true,
minChars: 3,
initComponent: function() {
    var me = this;
    Ext.applyIf(me, {
            //some templates
    });
    me.callParent(arguments);
}
});
ビューとストアとしてコンボボックスを構成するだけでよいコントローラーとしてコンポーネントを構築しようとしています:
Ext.define('MyApp.controller.SearchAsYouTypeComboboxController', {
extend: 'Ext.app.Controller',
stores: [
    'SearchAsYouTypeStore'
],
views: [
    'SearchAsYouTypeCombobox'
],
onComboboxBeforeQuery1: function(queryPlan, eOpts) {
    var me = this;
    //determine tokens
    //add filter per token
    //One could optimize by not clearing the filter when the query String is only extended (leading or trailing) and not changed.
    //consider maybe the tokens 
    //console.log('beforeQuery');
    var comboBox = queryPlan.combo;
    var myStore = comboBox.getStore(); 
    var queryString = queryPlan.query;
    var prevQueryString = comboBox.lastQuery || '';
    var words = Ext.String.splitWords(queryString);
    //var filterAllPropertiesFilter = {};
    console.log('Query String :' + queryString);
    console.log("Words: " + words);
    //console.log(Ext.JSON.encode(myStore.storeId));
    //myStore.clearFilter(true);
    if(!Ext.isEmpty(queryString))
    {
        var filters = [];
        //When query has not been only expanded
        if(prevQueryString && 
        (queryString.length <= prevQueryString.length || 
        queryString.toLowerCase().lastIndexOf(prevQueryString.toLowerCase(), 0) !== 0))
        {
            //Reload everything new
            myStore.remoteFilter = true;
            myStore.clearFilter(true); //careful with this, it loads all the data unfiltered!
            myStore.remoteFilter = false;
            console.log('Creating Filters for each word.');
            Ext.Array.each(words,
            function(word, index, allWords){
                me.currentFilterWord = word;
                console.log('NEW FILTER: word:' + word);
                var filterAllPropertiesFilter = Ext.create('Ext.util.Filter',
                    {filterString: word,
                    filterFn: me.filterAllPropertiesFn});
                filters.push(filterAllPropertiesFilter);
            });
        }
        else{   
            if(!prevQueryString){
                myStore.remoteFilter = true;
                myStore.clearFilter();
            }
            myStore.remoteFilter = false;
            //only for the last word
            me.currentFilterWord = words[words.length-1];
            console.log('NEW FILTER: word: ' + me.currentFilterWord);
            var filterAllPropertiesFilter = Ext.create('Ext.util.Filter',
                {filterString: me.currentFilterWord,
                filterFn: me.filterAllPropertiesFn});
            filters.push(filterAllPropertiesFilter);
            Ext.Array.each(myStore.filters.items,
            function(filter, index, allFilters){
                myStore.removeFilter(filter, false);
            });
            //myStore.filter(filterAllPropertiesFilter);
        }
        myStore.filter(filters);
        comboBox.lastQuery = queryString;
        //filterBy(filters);
    }
    else
    {
        myStore.clearFilter(false);
    }
    comboBox.expand();
    queryPlan.cancel = true;
    return queryPlan;
},
filterAllPropertiesFn: function(item) {
    // filter magic
},
filterOverride: function(filters, value) {
    //changed the filter to subsequently filter 
},
init: function(application) {
    var me = this;
    console.log("init of Controller");
    //when more than 1 store then error
    console.log("Stores: " + this.stores[0]);
    var myStoreName = this.stores[0];
    var MyStore = me.getStore(myStoreName);
    console.log("MyStore: " + MyStore.storeId);
    Ext.override(MyStore,{override: myStoreName,
    filter: me.filterOverride});
    var myComboBoxName = this.views[0];
    var MyComboBox = me.getView(myComboBoxName);
    console.log("MyComboName: " + myComboBoxName);
    console.log("Data: " + MyStore.data.collect('id'));
    MyComboBox.store = MyStore;
    Ext.override(MyComboBox, {override: myComboBoxName,
    store: MyStore});
    console.log("myCombo.store: " + MyComboBox.store.storeId);
    this.control({
        "combobox": {
            beforequery: this.onComboboxBeforeQuery1,
        }
    });
},
});