Слушатели ExtJS: анонимные параметры функции

Я взял этот код из какой-то книги, которую наткнулся в Интернете...

sm: new Ext.grid.RowSelectionModel({
   singleSelect: true,
   listeners: {
       rowselect: {
           fn: function(sm,index,record) {
               Ext.Msg.alert('You Selected',record.data.title);
           }
       }
   }
});

теперь sm является сокращением для модели выбора, мы обсуждаем здесь ExtJS GridPanel... Все ясно до части fn:. Насколько я знаю, анонимная функция передается с тремя параметрами: sm, index и record.

Прямо сейчас я собираюсь получить меньше голосов за вопрос о чем-то чрезвычайно тривиальном: как узнать, какие параметры вы должны передать? Если я пропущу индексный параметр, я получу ошибку... Почему я должен передавать 3 параметра? В чем подвох?


person aL3xa    schedule 03.08.2010    source источник


Ответы (2)


Рассмотрим этот сценарий:

//called with (selectionModelInstance, Index, Record)
function myCallback(sm,index,record) {
  //Parameter mapping:
  //sm -> selectionModelInstance
  //index -> Index
  //record -> Record
  alert(record.data);
  //record is actually a record object, so record.data works
}

Посмотрите, что происходит, когда вы пропускаете параметр:

//called with (selectionModelInstance, Index, Record)
function myCallback(sm,record) {
  //Parameter mapping:
  //sm -> selectionModelInstance
  //record -> Index
  alert(record.data); //Error
  //record is actually Index here, and it obviosly doesn't have data property.
}

Ошибка, которую вы видите, не имеет ничего общего с несоответствием параметров при вызове функции. Javascript позволяет вызывать любую функцию, принимающую любое количество параметров, с любым количеством параметров. Ошибка связана с попыткой разыменовать свойство record.data, которого там нет.

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

person Igor Zevaka    schedule 03.08.2010
comment
Да... это функция, специфичная для события, вы должны передать 3 параметра в точном порядке, иначе она выдаст ошибку! В этом случае функция связана с публичным событием rowSelect. Спасибо! - person aL3xa; 04.08.2010
comment
Просто чтобы уточнить предыдущий комментарий, вы должны передать все 3 параметра только в том случае, если вы действительно ИСПОЛЬЗУЕТЕ третий параметр. Он не выдаст ошибку, потому что вы упустите параметр — он выдаст ошибку, когда вы попытаетесь получить доступ к нулевой ссылке. Вам нужно указать только последний параметр, который вы действительно хотите использовать в функции — все остальные параметры после этого можно опустить. Это относится к функциям в целом, а не только к обработчикам событий. - person Brian Moeskau; 04.08.2010

Параметры не передаются по имени; они передаются по «позиции» (как и в большинстве других языков сценариев и программирования). Обратный вызов должен иметь три параметра, потому что вызывающая сторона предоставит три аргумента; если есть несоответствие, произойдет ошибка.

person You    schedule 03.08.2010
comment
Я знаю, что здесь используется позиционное сопоставление... чего я не понимаю, так это почему я должен передать 3 параметра: один для модели выбора, второй для индекса и третий для значения данных в сетке? - person aL3xa; 04.08.2010
comment
Извините, проблема с RTFM... кусок из официальной документации: rowselect : ( SelectionModel this, Number rowIndex, Ext.data.Record r ) так что, наконец-то, ретард понял: это функция, специфичная для события! - person aL3xa; 04.08.2010
comment
Нет, не поэтому. Причина, по которой вы должны принимать три параметра в своей функции, заключается в том, что extJS ожидает, что вы их примете. Смотрите ответ @IgorZevaka для более подробного объяснения. - person You; 04.08.2010