Использование Ext.form.Basic.loadRecord для загрузки данных в поля со списком с удаленными хранилищами

У меня есть форма с несколькими полями со списком, которые прикреплены к удаленным хранилищам:

Ext.define('app.ux.form.MyCombo', {
    extend: 'Ext.form.field.ComboBox',
    alias: 'widget.mycombo',
    store: this.store,
    displayField: 'displayField',
    valueField: 'valueField',
    forceSelection: true,
    autoSelect: true,
    initComponent: function() {
        this.addEvents('selectitem');
        this.enableBubble('selectitem');
        this.callParent(arguments);
        this.listeners = {
            change: function(field, value) {
                this.fireEvent('selectitem', field, value);
            }
        }
    }
})


                fieldLabel: 'DisabilityType',
                name: 'f_disability_type',
                xtype: 'combo',
                valueField: 'valueField',
                displayField: 'displayField',
                forceSelection: true,
                autoSelect: true,
                store: 'DisabilityTypes'

DisabilityTypes — это базовое хранилище Ext.data.store, для autoLoad которого задано значение false, а для autoSync — значение true. Когда вы нажимаете на раскрывающийся список, привязанный к магазину, магазин загружается и показывает список значений.

Когда я вызываю loadRecord для объекта BasicForm, который содержит это раскрывающееся меню, и передаю ему модель, он заполняет поля со списком, которые используют локальные хранилища, но не загружает поля со списком, которые используют удаленные хранилища. Это связано с тем, что либо хранилище поля со списком не загружено (autoLoad: false), либо поле со списком загружается ПОСЛЕ загрузки формы (autoLoad: true).

Я знаю, что это была проблема в Ext 3.3.x и что для ее устранения был создан плагин:

/**
 * When combo box is used on a form with dynamic store (remote mode) 
 * then sometimes the combobox store would load after the form data. 
 * And in that case the setValue method of combobox will not  
 * set the combobox value properly. This override makes sure that the
 * combobox store is completely loaded before calling the setValue method.
 */
Ext.override(Ext.form.ComboBox, {
    setValue : function(v){
        var text = v;
        if(this.valueField){
            if(!Ext.isDefined(this.store.totalLength)){
                this.store.on('load', this.setValue.createDelegate(this, arguments), null, {single: true});
                if(this.store.lastOptions === null){
                    var params;
                    if(this.valueParam){
                        params = {};
                        params[this.valueParam] = v;
                    }else{
                        var q = this.allQuery;
                        this.lastQuery = q;
                        this.store.setBaseParam(this.queryParam, q);
                        params = this.getParams(q);
                    }
                    this.store.load({params: params});
                }
                return;
            }
            var r = this.findRecord(this.valueField, v);
            if(r){
                text = r.data[this.displayField];
            }else if(this.valueNotFoundText !== undefined){
                text = this.valueNotFoundText;
            }
        }
        this.lastSelectionText = text;
        if(this.hiddenField){
            this.hiddenField.value = v;
        }
        Ext.form.ComboBox.superclass.setValue.call(this, text);
        this.value = v;
    }
});

Исправлена ​​ли эта проблема в Ext 4? Или мне нужно найти другой плагин, совместимый с Ext 4?


person Levi Hackwith    schedule 09.06.2011    source источник
comment
Он отлично работает, по крайней мере, в 4.0.7, я не знаю, какую версию вы используете, но если я вызову setvalue() для комбо с еще не загруженным хранилищем, а в хранилище есть autoLoad: true, тогда он загружает хранилище сначала, а затем устанавливает значение.   -  person VoidMain    schedule 18.11.2011


Ответы (3)


Мое решение:

Ext.form.field.ComboBox.override( {
    setValue: function(v) {
        v = (v && v.toString) ? v.toString() : v;
        if(!this.store.isLoaded && this.queryMode == 'remote') {
            this.store.addListener('load', function() {
                this.store.isLoaded = true;
                this.setValue(v);
            }, this);
           this.store.load();
        } else {
            this.callOverridden(arguments);
        }
    }
});
person Levi Hackwith    schedule 10.06.2011

просто еще одно переопределение - работает для меня, используя метод [form].loadRecord([model]).

будьте осторожны: если вы используете противоположный способ [form].updateReocrd([model]) значения параметров не будут использовать разделитель по умолчанию, а вместо этого просто ','.

Итак, если у вас есть loadRecord, сделайте что-нибудь, а затем вызовите updateRecord loadrecord позже, выборки будут потеряны из-за неправильного разделителя. Вот почему здесь выполняется сравнение "меньше 2"

Ext.form.field.ComboBox.override( {
    setValue: function(v) {
        if (this.multiSelect && typeof v != 'undefined' && typeof v.split == 'function'){
            if (this.value.length < 2){
                this.setValue(v.split(this.delimiter));
            }
        } else {
            this.callOverridden(arguments);
        }
    }
});
person Frogger    schedule 08.04.2014

person    schedule
comment
Чем это лучше принятого ответа? Комментарии к коду всегда приветствуются. - person Nikana Reklawyks; 30.10.2012