Ограничения фреймворков (на примере Yii)

Владимир | | Ajax, HTML, JavaScript, PHP, Web разработка, Yii.

yii php framework autocomplete

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

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

В этой статье я хочу показать пример такой ситуации, и, естественно, её решение.

UPD: Более удачное решение данной проблемы приведено в комментариях.

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

Алгоритм его работы довольно прост.

1) Создать текстовое поле (тег input).
2) Подключить плагин jQuery Autocomplete и файлы CSS стилей.
3) Подключить плагин к текстовому полю.

При этом, все настройки виджета CAutoComplete задаются при его подключении в PHP массиве.

Т.к. основную работу выполняет Autocomplete, то логично было бы предположить, что в настройках виджета можно задать все параметры этого плагина. Для большинства параметров, так оно и есть, но с параметром extraParams возникли проблемы.

В документации сказано.

Extra parameters for the backend. If you were to specify {bar:4}, the autocompleter would call my_autocomplete_backend.php?q=foo&bar=4 (assuming the input box contains «foo»). The param can be a function that is called to calculate the param before each request.

Дополнительный параметр для бэкенда. Если вы указали {bar:4}, плагин отправит запрос my_autocomplete_backend.php?q=foo&bar=4 (предполагается, что текстовое поле содержит текст «foo»). Параметр может быть функцией, которая вызывается чтобы рассчитать значение параметра перед отправкой каждого запроса.

Т.е. вы можете задать настройки для CAutoComplete следующим образом.

$this->widget('CAutoComplete',
     array(
         'extraParams'=>array('mypar'=>'myval'),
         'url'=>array('countries/autocomplete'),
     )
 );

И такой вариант будет работать.

Но если вы захотите использовать в качестве значения функцию, например

'extraParams'=>array('mypar'=>'function() {return $("#myselect").val();}'),

то этот JS код выполняться не будет.

Примечание. Показанная здесь функция возвращает значение из выпадающего списка (myselect).

Дело в том, что функция передается в виде стоки (в кавычках) и JS код при этом, естественно, не выполняется.

Решить проблему можно так.

1) Создаём js файл с таким кодом.

jQuery("#country").setOptions({
'extraParams':{'mypar':function() {return $("#myselect").val();}}}
);

2) Подключаем его к нужной странице.

$cs = Yii::app()->clientScript;
$cs->registerScriptFile(Yii::app()->request->baseUrl.'/js/autocomplete_config.js', CClientScript::POS_END);

Здесь autocomplete_config.js – название вашего скрипта.

Как видите, решение достаточно простое, но не очень красивое. Часть настроек виджета будет задана в PHP файле, часть в JS.

Если вы знаете более удачные варианты, буду рад выслушать и обсудить 😉

До встречи!

Интересно почитать

Удобный и недорогой стол для кассы отечественной разработки

  • Zifius

    можно попробовать добавить «js:» перед функцией.

  • alexeyvolkov

    А использование префикса «js:» не подходит?

    'extraParams'=>array('mypar'=>'js:function() {return $(«#myselect»).val();}'),

  • Да, я поспешил с выводами и зря «наехал» на Yii 🙂
    Вариант с js: работает.

  • Michael

    Сама постановка вопроса несколько странная. Всегда можно написать свой класс с нуля или расширить существующий. Например вот старая тема с форума
    http://www.yiiframework.com/forum/index.php?/to

  • Вы правы, написать свое решение всегда можно. Но, когда видишь готовый
    класс, который позволяет решить задачу, возникает желание его
    использовать. И если при этом появляются проблемы, то начинаешь
    прикидывать, то ли получится их по-быстрому исправить, то ли
    заниматься своим решением.

    А вообще, конечно, обойти можно любой компонент фреймворка, поэтому
    теоретически он действительно ограничений не накладывает 🙂

  • Castro

    Владимир, а нет у Вас в планах расказать о таком, набирающем популярность фреймворке как Symfony ?

  • Я бы не сказал, что Symfony «набирающий популярность» 🙂
    По-моему, он стал популярным довольно давно и используется во многих проэктах. Например, часть сервисов yahoo сделана с его использованием.
    Но рассказывать о нем не планирую, т.к. практически им не пользовался.

  • Вы правы, написать свое решение всегда можно. Но, когда видишь готовый
    класс, который позволяет решить задачу, возникает желание его
    использовать. И если при этом появляются проблемы, то начинаешь
    прикидывать, то ли получится их по-быстрому исправить, то ли
    заниматься своим решением.

    А вообще, конечно, обойти можно любой компонент фреймворка, поэтому
    теоретически он действительно ограничений не накладывает 🙂

  • Вы правы, написать свое решение всегда можно. Но, когда видишь готовый
    класс, который позволяет решить задачу, возникает желание его
    использовать. И если при этом появляются проблемы, то начинаешь
    прикидывать, то ли получится их по-быстрому исправить, то ли
    заниматься своим решением.

    А вообще, конечно, обойти можно любой компонент фреймворка, поэтому
    теоретически он действительно ограничений не накладывает 🙂

  • It looks good,I have learn a recruit!Recently,I found an excellent online store, the XX are completely various, good quality and cheap price,its worth buying! Nike Zoom Blur