Javascript 更新禁用字段的表单记录
我在ExtJS4中有一个复杂的表单,表单的各个部分根据用户从一些表单字段中选择的内容动态启用或禁用每当我禁用表单字段时,我也会清除它当前包含的任何值。 我有一个表示表单的模型类。要加载表单,我使用Javascript 更新禁用字段的表单记录,javascript,html,forms,extjs,Javascript,Html,Forms,Extjs,我在ExtJS4中有一个复杂的表单,表单的各个部分根据用户从一些表单字段中选择的内容动态启用或禁用每当我禁用表单字段时,我也会清除它当前包含的任何值。 我有一个表示表单的模型类。要加载表单,我使用form.loadRecord(model)。要在用户“提交”表单时更新我的模型,我使用model.set(form.getValues()) 问题是ext的getValues()实现跳过了禁用的表单字段。在我的例子中,这会导致问题,因为一些更改了值的表单字段被禁用(即,当我禁用它们时,其值被清除的表单
form.loadRecord(model)
。要在用户“提交”表单时更新我的模型,我使用model.set(form.getValues())
问题是ext的getValues()
实现跳过了禁用的表单字段。在我的例子中,这会导致问题,因为一些更改了值的表单字段被禁用(即,当我禁用它们时,其值被清除的表单字段)。因此,当我调用model.set(…)
时,这些字段不会在模型中更新(清除)
解决这个问题的最佳方法是什么?我考虑过以下的想法,但没有一个看起来很好。如果你有更好的,我想听
- 在调用
之前,清除模型(将所有字段设置为未定义)。不幸的是,没有model.setValues()
方法,所以这很快就会变得难看-我必须获取所有字段并遍历它们,逐个清除每个字段model.clear()
- 当我禁用和清除表单字段时,也清除模型字段。这似乎违反了关注点的分离,也意味着模型被更改,即使用户选择取消并不提交表单
- 重写ext对
的实现,以不跳过禁用的字段。这更难看,因为需要更改的实际代码位于form.getValues()
类中,而不是Ext.form.field.field
Ext.form.Basic
//Save record
form.updateRecord(this.record);
this.record.save();
this.record.commit();
如果这对您不起作用,我建议您编写一个名称类似的方法,并扩展表单面板以包含它,该方法获取值数组,然后遍历每个值并仅在值不为null时更新它。这是您在第三点中公开的解决方案: 更改此行为的唯一方法是重写此方法
Ext.override('Ext.form.field.Field', {
getSubmitData: function() {
var me = this,
data = null;
if (!me.isFileUpload()) {
data = {};
data[me.getName()] = '' + me.getValue();
}
return data;
}
});
关于你的第一点,拒绝(错误)有用吗
最新选项可以覆盖表单中每个字段的getSubmitData,如下所示:
{
xtype: 'textfield',
getSubmitData: this.getSubmitDataMyOwnVersion
}
我意识到这是一个老帖子,但我遇到了同样的问题。这是一个相当严重的问题,因为它会在您不知情的情况下导致数据问题。在我的例子中,当禁用时,我还将几个复选框设置为
false
,但由于其工作方式,它们在幕后被保留为true
作为一种解决方法,我现在遍历表单中的所有字段,并手动更新每个字段的记录。这需要更多的工作,但我不必重写任何类,而且循环具有足够的通用性,如果/当表单定义更改时,它将继续工作
var fields = this.getForm().getForm().getFields();
var record = this.getForm().getRecord();
for (var i = 0; i < fields.length; i++) {
var name = fields.items[i].name;
var value = fields.items[i].value;
record.set(name, value);
}
var fields=this.getForm().getForm().getFields();
var record=this.getForm().getRecord();
对于(变量i=0;i
请注意,马克·瓦格纳的回答打破了其他组件的任何高级组件/功能,因为它直接获取值,而不是获取getSubmitValue()。我不得不稍微修改Iontivero的答案,因为至少在4.2.0中,我发现Extjs调用的不是这个类
Ext.define('YourAppName.override.Field', {
override: 'Ext.form.field.Base',
getSubmitData: function() {
var me = this,
data = null,
val;
if (me.submitValue && !me.isFileUpload()) {
val = me.getSubmitValue();
if (val !== null) {
data = {};
data[me.getName()] = val;
}
}
return data;
}
});
然后在Ext.application中:
要求:['YourAppName.override.Field'],禁用的字段通常(不仅仅是extjs)总是从post数据中排除。而是将字段设置为只读。只读字段和禁用字段之间的平均区别在于。不幸的是,
updateRecord
使用了跳过禁用字段的相同底层代码。调用链是updateRecord->getFieldValues->getValues
,在这种情况下,我认为可以在当前面板上查询从Form.field.Base扩展的所有组件。然后循环,找到name属性,然后检查它是否是模型中的字段,以及isDisabled()是否为true。如果两者都为true,则在模型实例上调用setValue('FieldName',null)。不需要组件查询,因为已经存在Ext.form.Basic.getFields()
方法。我假定您的意思是model.reject(false)
。仅放弃自创建或上次提交以来对模型所做的更改。就我而言,我还没有任何更改(在model.set(…)
之前),因此调用reject
不会为我清除任何内容。这是对我有效的解决方案。请注意,另一种解决方案所建议的重写Ext.form.field.field
没有任何效果,因为该类是一个mixin,并且在mixin之后应用重写(这意味着更改永远不会转移到应用mixin的类)。因此,此处所示的Ext.form.field.Base
覆盖可以得到所需的结果