ajax & внешние скрипты

Есть такая задача каждый метод контроллера приложения, должен уметь ответить как на аякс так и на обычный запросы.

причем ответ каждого метода достаточно сложный интерфейс с кучкой яваскрипта.

Т.е. если запрос обычный, то метод отвечает вместе с layout’ом и всеми скриптами подключенными через CAssetManager,

а если это аякс запрос то никакого layout’a но есть нюансы со скриптами…

в принципе тут два варианта, либо:

  1. метод отправляет клиенту HTML без скриптов

  2. метод отправляет клиенту HTML со всеми или некоторыми скриптами

но вот как определить с какими нужно отправлять а с какими нет ? Ведь определить какой нужен а какой нет можно только на "клиенте".

Когда я говорю о скриптах, я говорю именно о файлх js (а не инлайн коде)

Решение которое мне закралось в голову:

  1. Каким-то образом дать системе знать что скрипты нам нужны но их публиковать не нужно.

  2. После того как output готов, подсунуть в него полученный список желаемых скриптов в виде js объекта.

  3. На клиенте первым делом проверить подключены ли уже на странице те JS файлы какие присутсвуют в нашем js объекте созданном на п2.

  4. Подключить только нужные скрипты

Вопросы:

  • Как получить все подклченные скрипты но при этом не публиковать их? Может быть во время региастрации скрипта можно как то решать этот вопрос, реализовав это в унаследованном классе ?

  • Как на клиенте проверять загружены ли уже файлы - возможный вариант: проходить все тэги script до исполнения любого яваскрипта, и сопостовлять их src тому что пришло с сервера в js объекте созданном в п2. ? и если требуемого файла нету то динамически его подключать, благо путь до него мы имеем уже в п2.

Как вам такой вариант ? или это слишком все усложняет ? Есть ли какой-то иной сособ ? обыскал весь форум и гугл вроде бы готовых решений не нашел.

Есть такое решение: http://www.yiiframework.com/extension/nlsclientscript/

Сам не пользовался, работает или нет, утверждать не буду, но подсмотреть что-то можно :)

Спасибо, то что доктор прописал !

В принципе даже немного проще чем то что я предложил в первом посте,

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

В любом случае, спасибо, проверил - работает так как нужно!

Подниму топик, так как сейчас сам столкнулся, как новичок в Yii, с проблемой контроля загрузки JS и CSS скриптов.

А именно:

система использует практически везде Ajax-запросы, и поэтому и всплыла эта проблема.

Опишу одну ветку:

=> Имеем страницу на которой расположен CJuiTab;

=> Контент каждого таба состоит из CGridView, подгружается AJAX-запросом;

=> По нажатию на строку открывается диалоговое окно (CJuiDialog) с сложной формой, подгрузка также AJAX-запросом;

=> В диалоговом окне есть свой CJuiTab + другие виджеты и т.д.;

В config/main.php




'components'=>array(

  'clientScript' => array(

//  'class' => 'application.components.NLSClientScript',

    'scriptMap' => array(

    'jquery.js' => '/js/jquery.js',

    'jquery-ui.min.js' => '/js/jquery-ui.js',

    'jquery-ui.css' => '/css/cupertino/jquery-ui.css',

  ),

),



Так вот, проблема в том что происходит после загрузки, слетает CSS-файл из-за перезагрузки этих данных.

Выдержка из FireBug:

GET index

GET jquery-ui.css

GET reset.css

GET style.css

GET jquery.js

GET jquery-ui.js

GET gettab?part=tab1

GET ui-bg_highlight-hard_100_f2f5f7_1x100.png

GET ui-bg_highlight-soft_100_deedf7_1x100.png

GET ui-bg_glass_50_3baae3_1x400.png

GET ui-bg_glass_80_d7ebf9_1x400.png

GET jquery.js?_=1325499506098

GET jquery.ba-bbq.js?_=1325499506663

GET jquery.yiigridview.js?_=1325499506969

GET bg.gif

GET jquery-ui.js?_=1325499507051

Это только часть, но на ней видно что jquery.js и jquery-ui.js перезагружаются дважды, после вызова диалога, тоже перезагружаются. И никак не могу найти где правильно вставить отлавливания этой подгрузки. При подключении NLSClientScript вовсе не производится загрузка виджета табов.

Честно говоря, вообще ставлю пока что для себя под вопрос целесообразность использования виджетов Yii. Очень хочется, так как с одной стороны удобно, но не будет ли это глюкать?

UPDATE: Вроде как разобрался, помогло такое решение в экшне:




    if (Yii::app()->request->isAjaxRequest)

    {

      // Stop jQuery from re-initialization

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

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

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

      ...

      $this->renderPartial('create',array('model'=>$model), false, true);



В дальнейшем естественно три строки объединены в одну и вынесены на пред-контроллер, чтобы это все отписывать одной строкой в дальнейшем.

Дополнительно была проблемы с тем, что для CJuiTab обязательно надо указывать id-шники, и не полагаться на автогенератор. Ну и так как была масса вложенных вьюшек, то для нормального рендеринга методом проб и ошибок, а после и просто обыязательно надо было разобраться с пониманием последней части renderPartial. В прошлый раз, полгода назад не дотянул немного до этого пункта и бросил “чтобы не тратить время” (отмазка), на этот раз пересилил себя и все получилось, Yii все так же продолжает радовать… :)