18 марта 2014 г., 18:30:38 Yii yii cjuidialog 0 Комментариев
Понадобилось сегодня сделать мне изменения поля в CGridView используя модальное окно. И вроде бы и всё хорошо, но при N-ом количестве раз открытия и закрытия окна CJuiDialog происходит дублирование запросов. Т.е. если я хочу обновить запись, то посылаю запрос update?id=3, и потом решаю обновить ещё одну, и посылаю запрос update?id=6. В итоге предыдущие запросы тоже выполняются ещё раз! Получается каша. Далее стало ясно, что если именовать кнопку submit как 'submit_' . rand(), то никакого дублирования не происходит.
Происходит кеширование событий для CHtml, т.к. ID (или name, смотря что используете) кнопки не изменяется от вызова до вызова модального окна, тем самым происходит множественные запросы. Лечить это можно по разному.
Лично моё мнение использовать 1й вариант, т.к. во втором варианте есть вероятность что-нибудь зацепить нужное из обработчиков, а третий вариант требует писанины кода . Но! 3й вариант самый лучший.
Так же можно посмотреть как это реализуется в файле CHtml строка с 2378.
Решение дублирования CSS и JS без строк типа
Yii::app()->clientScript->scriptMap['jquery.js'] = false;
Читаем, если ссылка ещё робит: http://www.eirikhoem.net/blog/2011/08/29/yii-framework-preventing-duplicate-jscss-includes-for-ajax-requests/
Или тупо подгружаем данных код в header:
$.ajaxSetup({ global: true, dataFilter: function(data, type) { // only 'text' and 'html' dataType should be filtered if (type && type != "html" && type != "text") { return data; } var selector = 'script[src],link[rel="stylesheet"]'; // get loaded scripts from DOM the first time we execute. if (!$._loadedScripts) { $._loadedScripts = {}; $._dataHolder = $(document.createElement('div')); var loadedScripts = $(document).find(selector); //fetching scripts from the DOM for (var i = 0, len = loadedScripts.length; i < len; i++) { $._loadedScripts[loadedScripts[i].src] = 1; } } //$._dataHolder.html(data) does not work $._dataHolder[0].innerHTML = data; // iterate over new scripts and remove if source is already in DOM: var incomingScripts = $($._dataHolder).find(selector); for (var i = 0, len = incomingScripts.length; i < len; i++) { if ($._loadedScripts[incomingScripts[i].src]) { $(incomingScripts[i]).remove(); } else { $._loadedScripts[incomingScripts[i].src] = 1; } } return $._dataHolder[0].innerHTML; } });
Комментарии [0]
Новый комментарий