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

31 мая, 2010
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 следующим образом.

  1. $this->widget('CAutoComplete',
  2.      array(
  3.          'extraParams'=>array('mypar'=>'myval'),
  4.          'url'=>array('countries/autocomplete'),
  5.      )
  6.  );

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

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

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

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

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

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

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

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

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

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

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

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

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

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

До встречи!

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

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

Понравилась статья? Подписывайтесь на продолжение rss link !

Или на мой твиттер twitter link

]]>

Добавьте эту страницу в google.com bobrdobr.ru del.icio.us technorati.com linkstore.ru news2.ru rumarkz.ru memori.ru moemesto.ru

]]>

Опубликовано в Ajax, HTML, JavaScript, PHP, Web разработка, Yii View Comments

]]>
  • Castro
    Владимир, а нет у Вас в планах расказать о таком, набирающем популярность фреймворке как Symfony ?
  • Я бы не сказал, что Symfony "набирающий популярность" :)
    По-моему, он стал популярным довольно давно и используется во многих проэктах. Например, часть сервисов yahoo сделана с его использованием.
    Но рассказывать о нем не планирую, т.к. практически им не пользовался.
  • Michael
    Сама постановка вопроса несколько странная. Всегда можно написать свой класс с нуля или расширить существующий. Например вот старая тема с форума
    http://www.yiiframework.com/forum/index.php?/topic/6037-cstringvalidator-%D0%B4%D0%BB%D0%B8%D0%BD%D0%B0-%D1%81%D1%82%D1%80%D0%BE%D0%BA%D0%B8/
  • Вы правы, написать свое решение всегда можно. Но, когда видишь готовый
    класс, который позволяет решить задачу, возникает желание его
    использовать. И если при этом появляются проблемы, то начинаешь
    прикидывать, то ли получится их по-быстрому исправить, то ли
    заниматься своим решением.

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

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

    А вообще, конечно, обойти можно любой компонент фреймворка, поэтому
    теоретически он действительно ограничений не накладывает :)
  • Да, я поспешил с выводами и зря "наехал" на Yii :)
    Вариант с js: работает.
  • А использование префикса "js:" не подходит?

    'extraParams'=>array('mypar'=>'js:function() {return $("#myselect").val();}'),
  • Alex
    можно попробовать добавить "js:" перед функцией.
blog comments powered by Disqus ]]>