简体   繁体   English

更新已禁用字段的表单记录

[英]Update form record for disabled fields

I have a complex form in ExtJS 4, where various parts of the form are dynamically enabled or disabled based on what the user selects from some of the form fields. 我在ExtJS 4中有一个复杂的表单,根据用户从某些表单字段中选择的内容,动态启用或禁用表单的各个部分。 Whenever I disable a form field, I also clear any value it currently has in it. 每当我禁用表单字段时,我也会清除它当前具有的任何值。

I have a model class representing the form. 我有一个表示表单的模型类。 To load the form, I use form.loadRecord(model) . 要加载表单,我使用form.loadRecord(model) To update my model when the user "submits" the form, I use model.set(form.getValues()) . 要在用户“提交”表单时更新我的​​模型,我使用model.set(form.getValues())

The problem is that ext's getValues() implementation skips form fields that are disabled. 问题是ext的getValues()实现会跳过禁用的表单字段。 This causes problems in my case, because some of form fields that have changed values are disabled (ie. form fields whose values I cleared when I disabled them). 这会导致我的问题,因为一些已更改值的表单字段被禁用(即表单字段,其值在我禁用它时清除)。 As a result, these fields are not updated (cleared) in the model when I call model.set(...) . 因此,当我调用model.set(...)时,模型中不会更新(清除)这些字段。

What would be the best way to work around this problem? 解决这个问题的最佳方法是什么? I've considered the following ideas, but none seems very good. 我考虑过以下想法,但似乎都没有。 If you have a better one, I'd like to hear it. 如果你有一个更好的,我想听听。

  • Clear the model (set all fields to undefined) before calling model.setValues() . 在调用model.setValues()之前清除模型(将所有字段设置为undefined model.setValues() Unfortunately, there is no model.clear() method, so this gets ugly quickly - I have to get all fields and iterate over them, clearing each one individually. 不幸的是,没有model.clear()方法,因此这很快变得丑陋 - 我必须获取所有字段并迭代它们,逐个清除每个字段。
  • Clear model fields also when I disable and clear the form fields. 当我禁用并清除表单字段时,也清除模型字段。 This seems to violate separation of concerns and also means the model gets changed, even when the user chooses to cancel and not submit the form. 这似乎违反了关注点的分离,也意味着模型会发生变化,即使用户选择取消而不提交表单也是如此。
  • Override ext's implementation of form.getValues() to not skip disabled fields. 覆盖ext的form.getValues()实现,以不跳过禁用的字段。 This is even more ugly because the actual code that needs to be changed is in the Ext.form.field.Field class, not Ext.form.Basic . 这更难看,因为需要更改的实际代码位于Ext.form.field.Field类中,而不是Ext.form.Basic

Disabled fields are commonly (not only extjs) always excluded from post data. 禁用字段通常(不仅仅是extj)总是从发布数据中排除。 Instead set fields readonly. 而是只读取字段。 The mean difference between readonly and disabled fields is just that. readonly和disabled字段之间的平均差异就是这样。

This is the solution that you exposed in the thrid point: The only way you have to change this behaviour is override this method. 这是您在第三点中公开的解决方案:您必须更改此行为的唯一方法是覆盖此方法。

Ext.override('Ext.form.field.Field', {
    getSubmitData: function() {
        var me = this,
            data = null;
        if (!me.isFileUpload()) {
            data = {};
            data[me.getName()] = '' + me.getValue();
        }
        return data;
    }
});

About your first point, isn´t .reject(false) useful? 关于你的第一点,不是.reject(false)有用吗?

The latest option could be override the getSubmitData for every single field in your form as follow: 最新的选项可以覆盖表单中每个字段的getSubmitData,如下所示:

{
   xtype: 'textfield',
   getSubmitData: this.getSubmitDataMyOwnVersion
}

I realize this is an old post but I have run into this same issue. 我意识到这是一个老帖子,但我遇到了同样的问题。 IMHO this is a rather serious issue because it can cause data problems without you knowing about it. 恕我直言,这是一个相当严重的问题,因为它可能会在您不知情的情况下导致数据问题。 In my case I also set several check boxes to false when disabled but because of the way this works they were being left as true behind the scenes. 在我的情况下,我还在禁用时将几个复选框设置为false ,但由于其工作方式,它们在幕后保持true

As a work around I now loop through all the fields in the form and manually update the record for each one. 作为一种解决方法,我现在遍历表单中的所有字段并手动更新每个字段的记录。 It's more work but I don't have to override any classes and the loop is generic enough that it will continue to work if/when the form definition is changed. 这是更多的工作,但我不必覆盖任何类,并且循环足够通用,如果/何时更改表单定义,它将继续工作。

    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);
    }

Note that Mark Wagoner's answer breaks any advanced components / features of other components since it takes the value directly rather then getting the getSubmitValue(). 请注意,Mark Waggoner的答案会破坏其他组件的任何高级组件/功能,因为它直接获取值而不是获取getSubmitValue()。 I had to slightly modify Iontivero's answer as that was not the class I found Extjs calling at least in 4.2.0. 我不得不略微修改Iontivero的答案,因为那不是我发现Extjs至少在4.2.0中调用的类。

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;
  }
});

then in Ext.application: requires: ['YourAppName.override.Field'], 然后在Ext.application中:需要:['YourAppName.override.Field'],

I haven't encountered that problem so far, but I update my model using the update() method rather than the setValue(). 到目前为止我还没有遇到过这个问题,但我使用update()方法而不是setValue()来更新我的模型。 Maybe it handles disabled fields differently? 也许它以不同方式处理禁用字段 Or maybe I'm headed down a path to need this answer as well since we're just starting major testing? 或者也许我正在走上一条需要这个答案的道路,因为我们刚刚开始进行重大测试? -- This is the basic usage of the Form.update method though, assuming form is an Ext.form.Panel and this.record is a model instance: - 这是Form.update方法的基本用法,假设form是一个Ext.form.Panel而this.record是一个模型实例:

//Save record
form.updateRecord(this.record);
this.record.save();
this.record.commit();

If that doesn't work for you, I would suggest writing a similarly named method and extending the form panel to include it that gets the array of values then goes through each one and updates it only if it's not null. 如果这对您不起作用,我建议编写一个类似命名的方法,并扩展表单面板以包含它,获取值数组然后遍历每个值并仅在它不为空时更新它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM