gpt4 book ai didi

javascript - EXT JS : In Combobox, 如何为不在商店中的记录设置显示字段?

转载 作者:行者123 更新时间:2023-11-30 17:50:59 27 4
gpt4 key购买 nike

我想在组合框中为记录(这是一个历史数据,存储在数据库中并加载到表单中)设置一个显示字段,该记录在数据库中没有条目。

例如,我在商店中有 3 个条目,如下所示 -值:显示字段一个苹果b : 球c : 猫

像往常一样,它用于预填充组合框(到这里工作正常)。

我在数据库中存储了历史数据,其中有一些记录的值id: d,它在商店中不再存在,但我仍然想支持旧数据并想用它显示关联的显示字段('doll')。

我的问题是,即使这条记录不在与组合框关联的商店中,如何设置从数据库中获取记录时的显示字段?目前,我们在 extJs 中没有诸如 setDisplayField 之类的方法,但是我们有一个方法“setValue”可以更改组合框中的值,这是不需要的。

我想在遇到来自数据库的“id =d”时将显示字段更改为“娃娃”。

请帮忙。

谢谢

最佳答案

如果您真正想要的是setDisplayField 方法,那么实际上它存在并且名为setRawValue。 .

但是,它本身是否足以解决您的问题值得怀疑。的确,你可能会用它来获得正确的显示,但你会失去你的值(value)......

var legacyData = [
{id: 'd', name: "Doll"}
];

var combo = Ext.widget({
renderTo: Ext.getBody()
,xtype: 'combo'
,fieldLabel: "Regular combo"
,valueField: 'id'
,displayField: 'name'
,queryMode: 'local'
,value: 'd'
,store: {
fields: ['id', 'name']
,data: []
,autoLoad: true
,listeners: {
load: function() {
var value = combo.value,
valueField = combo.valueField,
displayField = combo.displayField,
o = Ext.Array.findBy(legacyData, function(data) {
return data[valueField] === value;
});

if (o) {
combo.setRawValue(o[displayField]);
}

// Fail! This will alert 'Doll' instead of 'd'.
//
// If you set forceSelection to true, the value will be cleared
// all together.
//
alert(combo.getValue());
}
}
}
});

如 dbring 所建议的那样,将历史记录添加到组合的存储中确实可以解决您的问题,前提是您愿意让用户选择历史记录。据我了解,情况并非如此,否则您一开始就不会有任何问题...

在检查组合类的代码后,我认为实现您需要的最好方法是覆盖 findRecord方法。此方法返回的任何记录都将用于更新组合框显示及其值,与此记录是否存在于组合的存储中无关,并且不会影响可以在组合中选择的值。完美!

假设我们已经添加了一个 legacyStore 到我们的组合中,下面是如何覆盖 findRecord 方法来做到这一点:

findRecord: function(field, value) {
var ls = this.legacyStore,
record = this.callParent(arguments);
if (record) {
// found in current store
return record;
} else if (ls) {
// try legacy value store
var idx = ls.findExact(field, value);
return idx !== -1 ? ls.getAt(idx) : false;
} else {
return false;
}
}

现在,我们还有另外几个问题要处理...

首先,如果在调用 findRecord 时未加载遗留存储怎么办?那行不通的。在其普通形式中,如果未加载其存储,组合框将中止其 setValue 方法,并从其 onLoad 方法中回调它。我们应该添加一些代码来为我们的遗留商店复制此行为。

第二个问题更微不足道,但是如果组合是用历史值初始化的,而用户更改了组合的值但又后悔自己的选择怎么办?如果不取消并重新填写整个表格,他们将无法取回原始值。为了避免这种挫败感,我们可以更改组合行为以在清除时恢复其原始值,而不是其最后的值。由于我不知道这是否可取,我们将把它添加为一个选项。

考虑到所有这些,这里是将处理您的特定用例的“ux”的完整代码。

请注意,如果 forceSelection 设置为 true 并且商店是使用 autoLoad 创建的,它包括一个错误的全局修复,该错误会杀死组合框初始值: 真。有关更多信息,请参阅 this other question .或者,您可以跳过全局修复并将 loading: true 添加到使用 forceSelection: true 的组合的所有商店和遗留商店。

/**
* Fixes the bug with autoLoad: true and forceSelection: true.
*
* See: https://stackoverflow.com/a/14440479/1387519
*/
Ext.define('Ext.ux.fix.data.Store.AutoLoadLoadingState', {
override: 'Ext.data.Store'
,constructor: function() {
this.callParent(arguments);
if (this.autoLoad) {
this.loading = true;
}
}
});

/**
* A combo box with support for legacy values.
*
* Legacy values will be displayed if their value is assigned to the
* combo, but they won't be selectable (nor queryable) by the user.
*/
Ext.define('Ext.ux.form.field.LegacyValueCombo', {
extend: 'Ext.form.field.ComboBox'

,alias: 'widget.legacyvaluecombo'

,requires: [
'Ext.ux.fix.data.Store.AutoLoadLoadingState'
]

/**
* The store that provides legacy values.
*
* @cfg {Ext.data.Store/Object/String}
*/
,legacyStore: undefined

/**
* If `true` and {@link #forceSelection} is also `true`, the
* {@link #originalValue original value} of the field will be restored when
* the field is cleared, instead of the last value.
*
* This may be useful considering that if the combo original value is a
* legacy one, and the user changes this value, they will have no other
* means to get it back afterward.
*
* @cfg {Boolean}
*/
,restoreOriginalValue: true

/**
* Ensure the legacy store is a store instance before initializing the
* combo box.
*/
,initComponent: function() {

var legacyStore = this.legacyStore;
if (legacyStore) {
this.legacyStore = Ext.data.StoreManager.lookup(legacyStore);
}

this.callParent(arguments);
}

/**
* Overridden to return a legacy record if the value is not found in the
* regular store.
*
* This method will only work if both stores have been loaded.
*/
,findRecord: function(field, value) {
var ls = this.legacyStore,
record = this.callParent(arguments);
if (record) {
// found in current store
return record;
} else if (ls) {
// try legacy value store
var idx = ls.findExact(field, value);
return idx !== -1 ? ls.getAt(idx) : false;
} else {
return false;
}
}

/**
* This method is overridden to support the case where the legacy store
* loads after the regular store.
*/
,setValue: function(value) {
var store = this.store,
legacyStore = this.legacyStore;

if (legacyStore) {

// If the legacy store has not been loaded, trigger it.
if (!legacyStore.lastOptions) {
if (!legacyStore.loading) {
legacyStore.load();
}
}

// Legacy store is loading, we must wait for it to be done before
// processing the value.
if (legacyStore.loading) {

// This is done in the parent setValue method, but we are not
// sure it will be called in time so we must replicate this
// code here.
this.value = value;
this.setHiddenValue(value);

// If the regular store is loading, then this method will be
// called again when it is done. We will see at this time if we
// still have to wait for the legacy store. In the other case,
// we have to simulate a call to onLoad when the legacy store
// has loaded.
if (!store.loading) {
legacyStore.on({
single: true
,scope: this
,load: function(legacyStore, records, success) {
this.onLoad(store, store.getRange(), success);
}
});
}
}
// Legacy store is loaded, that's OK to continue.
else {
this.callParent(arguments);

// Implements restoreOriginalValue.
if (this.restoreOriginalValue) {
this.lastSelection = this.originalValue;
}
}

// setValue must return this
return this;
}
// No legacy store, just defer to the super method.
else {
return this.callParent(arguments);
}
}
});

最后,这是一个 live demo大量示例证明此用户体验适用于同步和异步存储以及 forceSelection 的所有组合...而 setRawValue 则不然。

关于javascript - EXT JS : In Combobox, 如何为不在商店中的记录设置显示字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19058128/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com