Передача параметров из контроллера в javascript-файлы

Javascript во вьюхах — часто ли вы встречаете такое?
Зачастую во вьюху из 3-5 строчек html-кода вставляются портянки яваскрипта на сотни строк.
На просьбу вынести этот код в отдельный js файл — можно услышать ответ, что в коде используются php-переменные из контроллера и, поэтому, вынести этот код из в отдельный js-файл не представляется возможным.

А в общем-то это довольно просто сделать. Просто и удобно.

Далее речь пойдет о реализации для фреймворка Yii, однако аналогичный подход легко реализуем и в других фреймворках.

В базовый класс контроллера добавляем публичное свойство $jsConfig = array();

В общий для всех страниц layout добавляем следующий кусок javascript-кода:

<script type="text/javascript">
	/*<![CDATA[*/
	var yii = yii || {};
	if (typeof yii.config === 'undefined') {
		yii.config = <?= CJavaScript::encode($this->jsConfig) ?>;
	} else {
		throw 'Yii js config cannot be defined because of name conflict!';
	}
	/*]]>*/
</script>


В нём к глобальному объекту yii добавляется свойство config, в которое передаются данные из публичного свойства $jsConfig контроллера.
Стоит отметить, что данный кусок кода нужно добавить в раздел <head> после подключения всех общих библиотек и до подключения своих js файлов.
Другие скрипты, подключаемые во вьюшках через registerScript будут добавляться уже после этого объявления.

 

Теперь внутри действий контроллера можно легко заполнять массив $jsConfig, например, вот так:

$this->jsConfig['uploadUrl'] = $this->createUrl('upload');

или

$this->jsConfig['tagsList'] = array('js', 'php', 'ruby', 'html');


И вышеуказанные данные авто-магически будут передаваться внутрь js-файлов и могут быть легко получены:

yii.config.uploadUrl

или

yii.config.tagsList

 

Довольно просто, не так ли? Данный подход можно также объединить с автоматическим подключением js-файлов, как это происходит, например, в Ruby On Rails, но это уже тема для другой статьи...