Как зарегистрировать скрипты и css виджета?

Необходимо при загрузке сайта зарегистрировать все скрипты виджетов, которые используются в интерфейсе, без загрузки оного.

К примеру, на странице используется CGridView, хотелось бы зарегистрировать его один раз (а не вызывать при переходах по ajax-табам). У него есть метод registerScript(), но его невозможно вызвать по причине того, что для его вызова требуется модель в CDataActiveRecord, а она уже должна формироваться позже динамически.

Как то это возможно по-человечески сделать? Или единственным вариантом остается разобрать скрипты виджетов, повытягивать из них registerScript() в отдельный набор и держать отдельный набор тупо для регистрации?

а что собственно требуеться

тоесть какова причина такого требования?

возможно вашей проблеме есть другое рещение

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

например что мешает разработичкам сделать отдельный статический метод лдя регистрации GridView jQuery плагина, а вот скрипт инициализации отдельно взятой грид пусть себе регистрируеться как обычно

Задача простая:

Цель: Загрузив единожды страницу - со страницы никуда не уходить, страница полностью под контролем ajax

  1. Страница на которой расположены JUITabs, контент табов подгружается ajax-ом;

  2. Контент табов представляет из себя CGridView (для каждого таба разные) с определенными фильтрами, колонками и т.д.;

  3. В этом же контенте появляются внутренние скрипты с различными действиями (для каждого таба могут быть разные, с разными ID);

Соответственно, при переходах по табам подгружается постоянно jquery.yiigridview.js,

казалось бы можно ведь тогда использовать:

_renderPartial($view, $params, false, [color="#FF0000"]FALSE[/color]);

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

Отслеживать постоянно состояние загружен-незагружен скрипт - тяжело, особенно на стадиях прототипирования, когда важна скорость разработки и наращивание базового функционала. С другой стороны хотелось подключение именно с asset’a, по принципу: ядро фреймворка - не трогать; переопределять - можно, изменять - запрещено!

Так вот и родились извращенные строки подключения в главном лейауте:


$gridScriptPath = Yii::app()->getAssetManager()->publish(Yii::getPathOfAlias('zii.widgets.assets.gridview'))."/jquery.yiigridview.js";

Yii::app()->clientScript->registerScriptFile($gridScriptPath);

в контроллере использую:


Yii::app()->clientScript->scriptMap['jquery.yiigridview.js']=false;

В итоге загружается этот скрипт только один раз.

Также с переходом по загруженными через 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 считаю решением через слишком заднее место, да и мне так и не удалось нормально заставить его работать, бывло что вырезало совсем не то что требовалось. Без обид разработчику скрипта, просто я не приемлю решения, в которых, нет жесткого контроля кода. Если невозможно определить что-либо на сервере, значит надо пересматривать архитектуру, если требуется проверки выполнять на стороне клиента, значит надо строить архитектуру по принципу: "семь раз проверь - один раз отрежь", чем "добавляй все что не лень, а потом проверяй и вырезай".

PS2: простите за "многабукф".

угу

использовал гриды с табами/акордеонами/… проблем не возникало, или проще сказать потом как разобрался не возникло

  1. строишь вьюв страници с табами

  2. в нужные табы кидаешь свои таблици но выносишь их в отдельные вьюшки




  // абстрактный код - не помню как там точно контент табов задаеться

  'tab1' => $this->renderPartial('_grid1',...),

  'tab2' => $this->renderPartial('_grid2',...),



  1. теперь при первом запуске страници CGridView зарегистрирует свои нужные скрипты

  2. при последующих обновлениях тбалиц они будут рендериться только сами а не все подряд

  3. только укажы для грид виджета 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 еще пользоваться нормально не научился, поэтому буду так же оные копать… :)