Не удается запустить прослушиватель событий изменения ExtJS - PullRequest
6 голосов
/ 02 декабря 2009

Меня попросили опубликовать это как вопрос на StackOverflow http://twitter.com/jonathanjulian, который затем был ретвитнут несколькими другими людьми. У меня уже есть некрасивое решение, но я отправляю исходную проблему в соответствии с просьбой.

Итак, вот предыстория. У нас есть массивное приложение базы данных, которое использует ExtJS исключительно для клиентской части. Мы используем GridPanel (Ext.grid.GridPanel) для представления строки, загруженного из удаленного хранилища.

В каждом из наших интерфейсов у нас также есть FormPanel (Ext.form.FormPanel), отображающая форму, которая позволяет пользователю создавать или редактировать записи из GridPanel. Столбцы GridPanel связаны с элементами формы FormPanel, поэтому при выборе записи в GridPanel все значения заполняются в форме.

В каждой форме у нас есть поле ввода для идентификатора строки таблицы (первичный ключ), который определяется следующим образом:

var editFormFields = [
{
     fieldLabel: 'ID',
     id: 'id_field',
     name: 'id',
     width: 100,
     readOnly: true, // the user cannot change the ID, ever.
     monitorValid: true
} /* other fields removed */
];

Итак, все в порядке. Это работает на всех наших приложениях. При создании нового интерфейса требовалось использовать сторонний API для хранения файлов, который предоставляет интерфейс в виде небольшой веб-страницы, загружаемой в IFrame.

Я поместил код IFrame внутри html-параметра FormPanel:

var editForm = new Ext.form.FormPanel({
   html: '<div style="width:400px;"><iframe id="upload_iframe" src="no_upload.html" width="98%" height="300"></iframe></div>',
   /* bunch of other parameters stripped for brevity */
});

Итак, всякий раз, когда пользователь выбирает запись, мне нужно изменить атрибут src IFrame на URL-адрес API службы, которую мы используем. Что-то вроде http://uploadsite.com/upload?appname=whatever&id={$id_of_record_selected}

Сначала я вошел в поле id (вставлено выше) и добавил прослушиватель изменений.

var editFormFields = [
{
     fieldLabel: 'ID',
     id: 'id_field',
     name: 'id',
     width: 100,
     readOnly: true, // the user cannot change the ID, ever.
     monitorValid: true,
     listeners: {
        change: function(f,new_val) {
           alert(new_val);
        }
     }
} /* other fields removed */
];

Красиво и просто, за исключением того, что это работает только тогда, когда пользователь сфокусирован на этом элементе формы. В остальное время он вообще не срабатывал.

Разочаровавшись, что я вышел за крайний срок и просто нуждался в том, чтобы он работал, я быстро реализовал затухающий опросчик, который проверяет значение. Это ужасный, уродливый хак. Но это работает, как ожидалось.

Я вставлю свой уродливый грязный хак в ответ на этот вопрос.

Ответы [ 3 ]

4 голосов
/ 02 декабря 2009

"Столбцы GridPanel связаны с элементы формы FormPanel так, чтобы когда запись выбрана в GridPanel, все значения заполняется в форме. "

Как я понимаю из приведенной выше цитаты, событие rowclick - это то, что фактически инициирует изменение вашей формы. Чтобы избежать опроса, это может быть место для прослушивания и, в конечном итоге, для вашего пользовательского события изменения.

1 голос
/ 02 декабря 2009

Вот уродливый взлом, который я сделал, чтобы решить эту проблему:

var current_id_value = '';
var check_changes = function(offset) {
   offset = offset || 100;
   var id_value = document.getElementById('id_field').value || '';
   if ( id_value && ( id_value != current_id_value ) ) {
      current_id_value = id_value;
      change_iframe(id_value);
   } else {
      offset = offset + 50;
      if ( offset > 2500 ) {
         offset = 2500;
      } 
      setTimeout(function() { check_changes(offset); }, offset);
   }
};

var change_iframe = function(id_value) {
   if ( id_value ) {
      document.getElementById('upload_iframe').src = 'http://api/upload.php?id=' + id_value;
   } else {
      document.getElementById('upload_iframe').src = 'no_upload.html';
   }   

   setTimeout(function() { check_changes(100); }, 1500);
};

Это не красиво, но работает. Все боссы счастливы.

0 голосов
/ 02 декабря 2009

Если вы потратили немного времени на чтение источника, вы увидите, что класс Ext.form.Field запускает только событие изменения в функции onBlur

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...