【问题标题】:ExtJS 4: How to know when any field in a form (Ext.form.Panel) changes?ExtJS 4:如何知道表单(Ext.form.Panel)中的任何字段何时更改?
【发布时间】:2011-12-19 19:18:29
【问题描述】:

我想要一个在表单(即 Ext.form.Panel)中的 any 字段发生变化时触发的单个事件监听器。但是,Ext.form.Panel 类本身不会触发事件。

侦听表单中所有字段的“更改”事件的最佳方式是什么?

【问题讨论】:

    标签: extjs extjs4


    【解决方案1】:

    更新:在 cmets 中添加了基于小费的第三个选项(感谢 @innerJL!)

    好的,看起来至少有两种相当简单的方法可以做到这一点。

    选项 1) 为添加到表单的每个字段添加一个“更改”侦听器:

    Ext.define('myapp.MyFormPanel', {
      extend: 'Ext.form.Panel',
      alias: 'myapp.MyFormPanel',
      ...
    
      handleFieldChanged: function() { 
        // Do something
      },
    
      listeners: {
        add: function(me, component, index) {
          if( component.isFormField ) {
            component.on('change', me.handleFieldChanged, me);
          }
        }
      }
    });
    

    这至少有一个很大的缺点;如果您将某些字段“包装”在其他容器中,然后将这些容器添加到表单中,它将无法识别嵌套字段。换句话说,它不会对组件进行“深度”搜索以查看它是否包含需要“更改”侦听器的表单字段。

    选项 2) 使用组件查询来侦听从容器中的字段触发的所有“更改”事件。

    Ext.define('myapp.MyController', {
      extend: 'Ext.app.Controller',
      ...
    
      init: function(application) {
        me.control({
    
            '[xtype="myapp.MyFormPanel"] field': {
                change: function() {
                  // Do something
                }
            }
        });
      }
    });
    

    选项 3) 侦听从表单面板的底层“基本”表单 (Ext.form.Basic) 触发的“dirtychange”。 重要提示:您需要通过确保将 {trackResetOnLoad:true} 传递给表单面板构造函数来确保必须启用“trackResetOnLoad”。

    Ext.define('myapp.MyFormPanel', {
      extend: 'Ext.form.Panel',
      alias: 'myapp.MyFormPanel',
      constructor: function(config) {
        config = config || {};
        config.trackResetOnLoad = true;
        me.callParent([config]);
    
        me.getForm().on('dirtychange', function(form, isDirty) {
           if( isDirty ) {
                // Unsaved changes exist
            }
            else {
                // NO unsaved changes exist
            }
        });
      }
    });
    

    这种方法是“最聪明的”;它可以让您知道表单何时被修改,以及用户是否将其修改回其原始状态。例如,如果他们将文本字段从“Foo”更改为“Bar”,则 'dirtychange' 事件将触发 isDirty 参数为 'true'。但是,如果用户随后将字段 back 更改为“Foo”,则 'dirtychange' 事件将触发 再次,并且 isDirty 将为 false

    【讨论】:

    • 也许这个 BasicForm 事件 (yourForm.getForm()) 可能对你有用docs.sencha.com/ext-js/4-0/#!/api/…
    • 如果有人有 ExtJs 3 的解决方案,我会很感兴趣。
    • 小心第三个选项。只有当表单的isDirty 属性发生变化时才会触发监听器。这意味着如果您有值为“Foo”的文本字段并且用户将该值更改为“Bar” - dirtychange 将被触发。但是如果用户再次将值更改为“池”dirtychange 将不会被触发,因为isDirty 属性已经是true
    【解决方案2】:

    我想补充克林特的回答。还有另一种方法(我认为它最适合您的问题)。只需将change 监听器添加到表单的默认配置中:

    Ext.create('Ext.form.Panel', {
        // ...
        defaults: {
            listeners: {
                change: function(field, newVal, oldVal) {
                    //alert(newVal);
                }
            }
        },
        // ...
    });
    

    【讨论】:

    • 感谢您的意见!就我而言,我实际上确实需要一个扩展表单面板的自定义类;我也只想知道字段何时从其原始值更改(“dirtychange”与“change”),但这对于不适用这两个要求的其他场景可能是很好的建议。
    • 表单面板中没有这个change事件,也不监听。
    • @Marshal。我没有写那个表格有这样的事件。表单域有这样的事件。在我的示例中,处理程序未分配给表单。它被分配给表单的所有字段。请参阅defaults 配置。
    • 您应该改用fieldDefaults,它将正确传播到字段组。
    猜你喜欢
    • 1970-01-01
    • 2016-07-20
    • 1970-01-01
    • 2013-07-27
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    • 2011-06-01
    • 2012-02-09
    相关资源
    最近更新 更多