It to hard to explain the problem in english. I try to explain in Russian. Sam Dark, can you explain the problems to mdomba ?
Как я понял команда yii хочет отказаться от undelegate перед delegate. Такой отказ вызовет ряд проблем в уже существущих аякс приложения. Как я уже писал раннее, в некоторых аякс приложениях обновляется целиком вся страница посредством renderPartial. И, для корректной работы этих приложений, необходимо(или-или):
- undelegate перед delegate, иначе события будут дважды навешаны на элемент. Однако, и при этом возникает ряд проблем.
Допустим мы повесили обработчик типа:
$("#body").delegate("a","click",function(e){
if(e.isDefaultPrevented()) return;
$("#content").load(this.href);
});
Рассмотрим что же происходит когда мы используем такой код. Но, сперва необходимо пояснить принцип delegate: обработчики обрабатываются сперва в порядке возврастания уровня контейнера в иерархии, а также внутри каждого из контейнеров delegate событий в порядке добавления этих событий. Отсюда следует, что для корректной работы тестового кода необходимо чтобы он вешался на body(так как CHtml::clientChange делегирует события на body и на этапе баблинга событие просто не достигнет нужных обработчиков) и чтобы был повешен после всех обработчиков, в противном случае он будет брать все события на себя и не давать другим обработчикам шанс выполниться. Отсюда и вытекает тот код что я опубликовал ранее. Допустим что undelegate перед delegate все же нет. Тогда, с любым из вариантов обработчика всех ссылок(правильным и нет) возникнут след. ситуации: "обработчик элемента"->"наш обработчик"->"дубли обработчика элемента"(1а) или "наш обработчик"-> "дубли обработчика элемента"(1б) для некорректного обработчика всех ссылок и "обработчик элемента"->"дубли этого же обработчика"->"наш обработчик всех ссылок"(2) для корректного. В некоторых случаях(1а и 2), когда обработчик элемента прерывает bubbling или возвращает false, то, казалось бы, все будет работать правильно, но, с большими утечками памяти. Во всех же остальных случаях либо после нашего обработчика уже ни один обработчик элемента не будет выполняться(1б), либо будут утечки памяти и риск мнодественной обработки одного и того же события одним и тем же обработчиком(то есть одним и тем же кодом обработчика, функции то разные). То есть возникнет так называемый geisen bug и утечки памяти. Более правильный вариант решения это вариант 2. Мало того, в текущей документации yii плохо раскрыт факт разницы между delegate и bind, в частности, в чем отличия при return false внутри обработчика для каждого из случаев. Так же стоит подчеркнуть, что delegate работает медленней чем bind.
- Использовать bind вместо delegate. Однако, в виду некоторых особенностей yii, для этого требуется ручной поиск всех мест где хелпер CHtml с использованием clientScript и явно не указано использование bind-а. Для этого требуется доп. анализ кода и это очень трудоемкий процесс. И после того как такие места выявлены, везде необходимо указать live=>false. Проблема вроде бы решается через свой хелпер, EHtml например, который переопределит реализацию clientChange. Однако из-за того что в php5.3 есть late static binding, то есть простое переопределение одного статического метода в подклассе(потомке CHtml) не поможет. Для решения проблемы через свой хелпер придется продублировать все методы из CHtml использующие clientChange c явным указанием не использовать live и вызовом родительской реализации. Переопределение поведения clientChange при это не требуется.
Вполне очевидно, что, учитывая моменты в 1 и 2, а так же и то, что jq пререшло на новый интерфейс - on/off и проблемы с delegate, описанные выше логично отказаться от delegate/сделать отключенным его по-умолчанию(+желательно иметь возможность указывать делигируемый контейнер)/добавить статическое св-во в CHtml ответственное за отключение delegate кроме принудительных случаев.
Еще раз подчеркну - да, сейчас все работает отлично. Меня все устраивает. Но, я раскрыл ряд моментов которые стоит учесть, иначе будут описанные проблемы.