ExtJS 4: Как узнать, когда изменяется любое поле в форме (Ext.form.Panel)? - PullRequest
11 голосов
/ 19 декабря 2011

Мне бы хотелось, чтобы один прослушиватель событий запускался всякий раз, когда любое поле в форме (т.е. Ext.form.Panel) изменяется. Однако класс Ext.form.Panel не запускает событие для этого самого.

Как лучше всего прослушивать события «изменения» для всех полей в форме?

Ответы [ 2 ]

19 голосов
/ 19 декабря 2011

Обновление : добавлена ​​третья опция на основе подсказки в комментариях (спасибо @innerJL!)

Хорошо, похоже, есть как минимум два довольно простых способа сделать это.

Вариант 1) Добавить прослушиватель 'change' для каждого поля, добавляемого в форму:

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

Это имеет как минимум один большой недостаток; если вы «обернете» некоторые поля в других контейнерах, а затем добавите эти контейнеры в форму, он не распознает вложенные поля. Другими словами, он не выполняет «глубокий» поиск по компоненту, чтобы определить, содержит ли он поле формы, для которого нужны слушатели «change».

Вариант 2) Используйте компонентный запрос для прослушивания всех событий 'change', запущенных из полей в контейнере.

Ext.define('myapp.MyController', {
  extend: 'Ext.app.Controller',
  ...

  init: function(application) {
    me.control({

        '[xtype="myapp.MyFormPanel"] field': {
            change: function() {
              // Do something
            }
        }
    });
  }
});

Вариант 3) Прослушайте «dirtychange», запущенный из базовой «базовой» формы панели форм (Ext.form.Basic). Важно : Вам необходимо убедиться, что вы должны включить 'trackResetOnLoad', обеспечив передачу {trackResetOnLoad: true} конструктору панели форм.

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 будет вызывать значение «true» для параметра isDirty. Но если затем пользователь изменит поле back на «Foo», событие dirtychange снова вызовет , а значение isDirty будет false .

6 голосов
/ 29 декабря 2011

Я хочу дополнить ответ Клинта. Есть еще один подход (и я думаю, что он лучше для вашей проблемы). Просто добавьте change слушатель к конфигурации формы по умолчанию:

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