extJS. Destroy и Render полей формы
Здравия.
У меня есть форма, в которой используются свои combobox-ы. Надо при выборе в первом select-е подгружать данные из базы во второе в зависимости от выбранного варианта в первом. С подгрузкой мне помог Сергей. Мне удалось сделать так, чтобы при выборе в первом поле во второе подгружались нужные варианты выбора. Однако если мы первый раз подгрузили в это поле данные, то второй раз они внешне никак не обновляются, хотя значения обновляются. Я так понял для этого надо разрушить и отрендерить поле заново. А вот как это сделать? Я получил нужное поле при событии select в первом Ext.getCmp( config.id +'-version'), выполняю в нём метод destroy(), а далее он уже не выполняет метод render(). Поле не появляется.
Вот код моих полей в форме:
У меня есть форма, в которой используются свои combobox-ы. Надо при выборе в первом select-е подгружать данные из базы во второе в зависимости от выбранного варианта в первом. С подгрузкой мне помог Сергей. Мне удалось сделать так, чтобы при выборе в первом поле во второе подгружались нужные варианты выбора. Однако если мы первый раз подгрузили в это поле данные, то второй раз они внешне никак не обновляются, хотя значения обновляются. Я так понял для этого надо разрушить и отрендерить поле заново. А вот как это сделать? Я получил нужное поле при событии select в первом Ext.getCmp( config.id +'-version'), выполняю в нём метод destroy(), а далее он уже не выполняет метод render(). Поле не появляется.
Вот код моих полей в форме:
{
xtype: 'hostpanel-combo-cms',
fieldLabel: _('hostpanel_site_cms'),
name: 'cms',
id: config.id +'-cms',
anchor: '100%',
listeners: {
'select': {
fn: function (o) {
var hostpanel_combo_version = Ext.getCmp( config.id +'-version');
hostpanel_combo_version.store = new Ext.data.JsonStore({
id: 0,
root: 'results',
totalProperty: 'total',
autoLoad: true,
fields: ['value', 'display'],
url: hostPanel.config.connector_url,
baseParams: {
action: 'mgr/settings/getlist',
key: 'version',
parent: o.value,
},
});
hostpanel_combo_version.destroy();
setTimeout(function(){
hostpanel_combo_version.render();
},1000);
}, scope:this
},
},
}, {
xtype: 'hostpanel-combo-version',
fieldLabel: _('hostpanel_site_version'),
name: 'version',
id: config.id +'-version',
anchor: '100%',
}
Поблагодарить автора
Отправить деньги
Комментарии: 12
Подход абсолютно не правильный. Ничего удалять не надо. У каждого комбобокса есть store. Нужно для store второго комбобокса указать выбранное значение в качестве параметра baseParams, а в его getlist процессоре учитывать этот параметр для ограничения запроса. Затем перечитать store.load().
Дал направление для самостоятельной попытки. Если не получится, пиши.
Дал направление для самостоятельной попытки. Если не получится, пиши.
Пишу вот такую штуку в то же событие select:
GetList процессор у меня уже обрабатывает ограничения по полю parent на основании value.o (значения, выбранного в первом combobox-е). Даже больше — он отдаёт в ExtJS нужные мне данные. Только вот отобразить во втором combobox-е я их пока не могу.
{
xtype: 'hostpanel-combo-cms',
fieldLabel: _('hostpanel_site_cms'),
name: 'cms',
id: config.id +'-cms',
anchor: '100%',
listeners: {
'select': {
fn: function (o) {
var hostpanel_combo_version = Ext.getCmp( config.id +'-version');
hostpanel_combo_version.store.load( hostpanel_combo_version.store, new Ext.data.JsonStore({
id: 0,
root: 'results',
totalProperty: 'total',
autoLoad: true,
fields: ['value', 'display'],
url: hostPanel.config.connector_url,
baseParams: {
action: 'mgr/settings/getlist',
key: 'version',
parent: o.value,
},
}) );
}, scope:this
},
},
}, {
xtype: 'hostpanel-combo-version',
fieldLabel: _('hostpanel_site_version'),
name: 'version',
id: config.id +'-version',
anchor: '100%',
}
GetList процессор у меня уже обрабатывает ограничения по полю parent на основании value.o (значения, выбранного в первом combobox-е). Даже больше — он отдаёт в ExtJS нужные мне данные. Только вот отобразить во втором combobox-е я их пока не могу.
Сергей, вот смотри. Я вот этим кодом могу обновлять значения в combobox-е, только он внешне пункты при выпадении вариантов выбора не обновляет:
Получается вот так:
Тут я кликаю на выпавший пункт, а он мне показывает выбранным совсем другой, тот, который подгрузил мне GetList.
hostpanel_combo_version.store = new Ext.data.JsonStore({
id: 0,
root: 'results',
totalProperty: 'total',
autoLoad: true,
fields: ['value', 'display'],
url: hostPanel.config.connector_url,
baseParams: {
action: 'mgr/settings/getlist',
key: 'version',
parent: o.value,
},
});
Получается вот так:
Тут я кликаю на выпавший пункт, а он мне показывает выбранным совсем другой, тот, который подгрузил мне GetList.
Если понять принцип работы компонентов, то все становится просто
'select': {
fn: function (o) {
var hostpanel_combo_version = Ext.getCmp( config.id +'-version'),
store = hostpanel_combo_version.store;
// Удаляем старые записи из комбобокса
store.removeAll();
// Прописываем нужный параметр для getlist процессора
store.baseParams['parent'] = o.value;
// Зачитываем новые записи
store.load();
// Очищаем поле комбобокса
hostpanel_combo_version.setValue('');
}, scope:this
}
Спасибо, Сергей, тебе огроменное! Это работает! Очень жду очередную твою статью по ExtJS! :)
Велком!
Сергей, если не затруднит, подскажи пожалуйста.
Я создаю свой комбобокс, мне надо, чтоб при выборе отображался один текст, а на сервер уходили только значения. Вот код комбобокса:
Проблема в том, что на сервер уходит текст displayField: 'display', а не значение valueField: 'value'. В доках смотрел и не нашёл такого параметра. Может ты знаешь, как это решить?
P.S.: Если в displayField подставляем 'value', то сохраняет правильно. Но так не надо.
Я создаю свой комбобокс, мне надо, чтоб при выборе отображался один текст, а на сервер уходили только значения. Вот код комбобокса:
hostPanel.combo.version = function(config) {
config = config || {};
Ext.applyIf(config, {
store: new Ext.data.JsonStore({
id: 0,
root: 'results',
totalProperty: 'total',
autoLoad: true,
fields: ['value', 'display'],
url: hostPanel.config.connector_url,
baseParams: {
action: 'mgr/settings/getlist',
key: 'version',
},
listeners: {
'clear': { fn: function(obj) { this.hide(); }, scope:this },
'load': { fn: function(obj, recs, opts) { obj.getTotalCount() > 0 && this.show(); }, scope:this },
},
}),
mode: 'local',
displayField: 'display',
value: 'value',
valueField: 'value',
typeAhead: true,
triggerAction: 'all',
});
hostPanel.combo.version.superclass.constructor.call(this,config);
};
Ext.extend(hostPanel.combo.version, MODx.combo.ComboBox);
Ext.reg('hostpanel-combo-version', hostPanel.combo.version);
Проблема в том, что на сервер уходит текст displayField: 'display', а не значение valueField: 'value'. В доках смотрел и не нашёл такого параметра. Может ты знаешь, как это решить?
P.S.: Если в displayField подставляем 'value', то сохраняет правильно. Но так не надо.
У комбобокса, как и у любого поля формы, должно быть имя — атрибут name, а также hiddenName. Они должны совпадать друг с другом. А для зачитки данных с сервера нужно указать mode: 'remote'.
Спасибо, Сергей! Сначало не понял, вроде указал поле name, думал этого достаточно. Не понимал, при чём тут hiddenName. Когда подставил — всё получилось. Никогда бы не подумал, что этот параметр мне поможет. Спасибо ещё раз, Сергей, ты мне очень помог!
Удалось решить вот так:
Только теперь, если не кликнул на второе поле перед тем, как выбрал что-нибудь в первом, в консоли вылазит вот такая ошибка:
И вылазит до тех пор, пока не кликнем на втором поле. Не знаешь, что на это влияет?
{
xtype: 'hostpanel-combo-cms',
fieldLabel: _('hostpanel_site_cms'),
name: 'cms',
id: config.id +'-cms',
anchor: '100%',
listeners: {
'select': {
fn: function (o) {
var hostpanel_combo_version = Ext.getCmp( config.id +'-version');
hostpanel_combo_version.reset();
hostpanel_combo_version.store = new Ext.data.JsonStore({
id: 0,
root: 'results',
totalProperty: 'total',
autoLoad: true,
fields: ['value', 'display'],
url: hostPanel.config.connector_url,
baseParams: {
action: 'mgr/settings/getlist',
key: 'version',
parent: o.value,
},
});
hostpanel_combo_version.bindStore( hostpanel_combo_version.getStore() );
}, scope:this
},
},
}, {
xtype: 'hostpanel-combo-version',
fieldLabel: _('hostpanel_site_version'),
name: 'version',
id: config.id +'-version',
anchor: '100%',
}
Только теперь, если не кликнул на второе поле перед тем, как выбрал что-нибудь в первом, в консоли вылазит вот такая ошибка:
И вылазит до тех пор, пока не кликнем на втором поле. Не знаешь, что на это влияет?
Павел, не выяснилось в чём была проблема с «Cannot read property 'setWidth' of undefined»?
Учусь на этом примере, то же самое вылезло, что не удивительно )
Работает всё нормально.
Учусь на этом примере, то же самое вылезло, что не удивительно )
Работает всё нормально.
Решить удалось, но переписав все по иному. Сейчас бы сделал все гораздо иначе и правильнее. :)
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.