ExtJS 4:如何知道表单(Ext.form.Panel)中的任何字段何时更改?

11

我希望有一个事件监听器,能够在表单(即Ext.form.Panel)中任何字段发生更改时触发。然而,Ext.form.Panel类本身不会触发此类事件。

如何最好地监听表单中所有字段的“change”事件?

2个回答

19

更新:根据评论中的提示添加了第三个选项(感谢@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的方式触发。但是,如果用户随后将该字段改回“Foo”,则“dirtychange”事件将再次触发,并且isDirty将为false


1
也许 BasicForm 的这个事件 (yourForm.getForm()) 对你有用,可以参考这里的文档:http://docs.sencha.com/ext-js/4-0/#!/api/Ext.form.Basic-event-dirtychange - Andrey Selitsky
如果有人对ExtJs 3有解决方案,我会很感兴趣。 - gunnx
1
请注意第三个选项。只有当表单的“isDirty”属性更改时,才会触发侦听器。这意味着,如果您有一个值为“Foo”的文本字段,并且用户将该值更改为“Bar”,则会触发“dirtychange”。但是,如果用户再次更改值为“Pool”,则不会触发“dirtychange”,因为“isDirty”属性已经为“true”。 - Nikolai Lopin

6
我想补充一下Clint的回答。还有一种方法(我认为这是你的问题最好的解决方案)。只需将change监听器添加到表单的默认配置中即可:
Ext.create('Ext.form.Panel', {
    // ...
    defaults: {
        listeners: {
            change: function(field, newVal, oldVal) {
                //alert(newVal);
            }
        }
    },
    // ...
});

感谢您的输入!在我的情况下,我实际上需要一个扩展表单面板的自定义类;此外,我只想知道字段何时从其原始值更改('dirtychange' vs. 'change'),但这可能是其他情况下的好建议,其中这两个要求不适用。 - clint
表单面板中没有这样的更改事件,也没有监听它。 - Marshal
2
@Marshal。我没有写那个表单有这样的事件。表单字段有这样的事件。在我的例子中,处理程序没有被分配给表单。它被分配给表单的所有字段。请参阅defaults配置。 - Molecular Man
你应该使用 fieldDefaults,它会正确地传播到字段组。 - Steve Dodier-Lazaro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接