Необходимо при загрузке сайта зарегистрировать все скрипты виджетов, которые используются в интерфейсе, без загрузки оного.
К примеру, на странице используется CGridView, хотелось бы зарегистрировать его один раз (а не вызывать при переходах по ajax-табам). У него есть метод registerScript(), но его невозможно вызвать по причине того, что для его вызова требуется модель в CDataActiveRecord, а она уже должна формироваться позже динамически.
Как то это возможно по-человечески сделать? Или единственным вариантом остается разобрать скрипты виджетов, повытягивать из них registerScript() в отдельный набор и держать отдельный набор тупо для регистрации?
я сам задавался таким вопросом в прошлом, очень часто не хватает такой функции зарегить скрипт без вызова самого виджета, я понимаю что не для всех виджетов это можно сделать… хотя как смотреть
например что мешает разработичкам сделать отдельный статический метод лдя регистрации GridView jQuery плагина, а вот скрипт инициализации отдельно взятой грид пусть себе регистрируеться как обычно
, но в этом случае не будут регистрироваться все внутренние скрипты.
Отслеживать постоянно состояние загружен-незагружен скрипт - тяжело, особенно на стадиях прототипирования, когда важна скорость разработки и наращивание базового функционала. С другой стороны хотелось подключение именно с asset’a, по принципу: ядро фреймворка - не трогать; переопределять - можно, изменять - запрещено!
Так вот и родились извращенные строки подключения в главном лейауте:
Также с переходом по загруженными через ajax-табы были замечены масса глюков с выводом типов данных в колонках, например: CCheckBoxColumn + CGridView SelectableRows. Загрузив другой таб и вернувшись после на первый, мы уже не сможем использовать штатные средства CCheckBoxColumn. Всплывшую проблему описал ниже (undelegate/unbind). Пришлось полностью переписать отображение для колонки CCheckBoxColumn, и заодно и JS-скрипты по выборке, ну и немного естественно их расширить под себя. Не выкладываю сюда, по причине того что пока еще… эм, стесняюсь, что-ли. Просто я не знаю постиг ли я true-way-of-Yii, поэтому как бы не уверен, что мой код является корректным по философии Yii. Как я уже говорил выше, сейчас пока только осваиваю дзэн Yii и занимаюсь прототипированием ресурса на базе фреймворка, для того чтобы знать насколько быстро можно реализовать ту или иную функцию, и наткнуться на максимально возможное количество граблей, ибо никакая теория "ЕщеОдногоБложика" не создаст боевых условий.
Так вот, из selectedrows + ccheckboxcolumn вытекла другая проблема, с jQuery .bind/.live и открытие форм различных ajax-ом. Приходится везде контролировать создаваемые действия и вызывать undelegate(). Вот думаю как бы это правильнее оформить в namespace-ы для того, чтобы можно было по namespace-у делать undelegate(). Оно, кстати, позволяет это делать, но вот все никак времени не хватает на то, чтобы автоматически генерировать у каждой страницы таковой список.
PS: Использование NLSClientScript считаю решением через слишком заднее место, да и мне так и не удалось нормально заставить его работать, бывло что вырезало совсем не то что требовалось. Без обид разработчику скрипта, просто я не приемлю решения, в которых, нет жесткого контроля кода. Если невозможно определить что-либо на сервере, значит надо пересматривать архитектуру, если требуется проверки выполнять на стороне клиента, значит надо строить архитектуру по принципу: "семь раз проверь - один раз отрежь", чем "добавляй все что не лень, а потом проверяй и вырезай".
использовал гриды с табами/акордеонами/… проблем не возникало, или проще сказать потом как разобрался не возникло
строишь вьюв страници с табами
в нужные табы кидаешь свои таблици но выносишь их в отдельные вьюшки
// абстрактный код - не помню как там точно контент табов задаеться
'tab1' => $this->renderPartial('_grid1',...),
'tab2' => $this->renderPartial('_grid2',...),
теперь при первом запуске страници CGridView зарегистрирует свои нужные скрипты
при последующих обновлениях тбалиц они будут рендериться только сами а не все подряд
только укажы для грид виджета action по которому он будет обновлять свой контент или можешь и не укзаывать тогда запрашивать будет по текущему контроллеру/действию
приблизительно у тебя будет такой код
/**
* Displays a particular model.
*/
public function actionView() {
$model = $this->loadModel();
// здесь рендерим наши таблици
$this->renderAjaxTables($model, ....);
// начальная инициализация моделей для таблиц
$ogoods = new OGoods();
$ogoods->unsetAttributes();
...
$this->render('view', array(
'model' => $model,
'ogoods' => $ogoods,
'simpleView' => true,
));
}
private function renderAjaxTables($model, $data=array()) {
if (isset($_GET['ajax'])) {
switch ($_GET['ajax']) {
case 'select-client-grid':
...
$this->renderPartial('_selectClient', array('model' => $client)+$data);
Yii::app()->end();
break;
case 'select-shipping-grid':
...
$this->renderPartial('_selectShipping', array('model' => $shipping+$data));
Yii::app()->end();
break;
case 'goods-order-grid':
...
$this->renderPartial('_viewOGoods', array('model' => $ogoods, 'order' => $model)+$data);
Yii::app()->end();
break;
case 'goods-for-order-grid':
...
$this->renderPartial('_selectGoods', array('model' => $gfo)+$data);
Yii::app()->end();
default:break;
}
}
}
как видишь очень много CGridView виджетов на одной странице
не свовсем понял в чем проблема с bind/live может это при твоем подходе так вылазит, но если нужно переинициализировать какието скрипты после обновления таблици смотри в сторону afterAjaxUpdate в CGridView.
единсвенное что помню была одна трабла - таблица после какогото обновления имела ширину большую чем вообще надо, не помнб как решил
и последнее
мой подход работает для тех табов которые уже имеют какой контент (таблици), если же табы грузят свой контент по AJAX то придеться извращаться по более
Это то что я имел ввиду, т.е. не знаком еще с корректной философией. Потому и копаю пока что в разные стороны чтобы опробовать тот или иной подход.
В том то и дело что хочется грузить все AJAXом, так как гриды не маленькие, и загружать их все сразу же не очень хочется. Более того в этом же контенте грузится инициализируется часть интерфейса, со своими диалоговыми окнами, в которых тоже есть и табы, в которых тоже есть гриды, т.е. загрузить сразу же все всеравно не получится. Т.е. связи между этими таблицами довольно развернутые. Хочу реализовать максимум возможных связей. ЧТобы к примеру из таблицы товары, можно было выйти не только на поставщиков этих товаров, но и на человека который запрашивал этот товар последний раз и его же карточку в том числе. При всем при этом со страницы нельзя уходить.
Функциями типа afterAjaxUpdate еще пользоваться нормально не научился, поэтому буду так же оные копать…