Zend Framework формы, декораторы и проверки: должен ли я вернуться к простому HTML?
В настоящее время я работаю над довольно большим приложением, которое содержит множество форм.
До этого момента я всегда писал свои формы вручную и писал свою собственную логику проверки, но я решил, что пришло время использовать Zend_Form и встроенные процедуры проверки.
Тем не менее, я продолжаю сталкиваться с все более и более проблемами, связанными с (отсутствием) гибкости, вызванной Zend_Form_Decorator
. Простые задачи, такие как добавление дополнительной кнопки в один элемент ввода, становятся невероятно трудными задачами.
Теперь я понял, что серьезно рассматриваю возможность сброса Zend_Form_Element
+ Zend_Form_Decorator
полностью, но я не хочу потерять отличные варианты проверки.
В принципе, я хочу лучшее из обоих миров:
- Запись форм так, как видит их конечный пользователь: в обычном HTML
- Легко добавлять проверки на стороне сервера для формирования полей, не нарушая слишком много стандартного поведения ZF
Возможное решение, которое я рассматриваю, заключается в написании форм как на стороне сервера, так и в представлениях. Это позволило бы мне легко проверить мои собственные формы, но (в моих глазах довольно большой) недостаток состоит в том, что каждая форма должна быть определена дважды, что просто кажется неправильным.
Есть ли какие-либо рекомендации для этого? Кто-нибудь из вас испытал то же самое, и если да, то как вы решили эти проблемы?
Я очень хотел бы услышать ваши точки зрения.
Ответы
Ответ 1
Я также считаю, что декораторы по умолчанию являются огромной болью. Я понимаю, почему они такие, каковы они есть, но я думаю, что "фактор неудобства" был сильно недооценен.
В любом случае, я бы рекомендовал использовать ViewScripts для ваших форм. Обратите внимание, что это не то же самое, что Views - вместо этого, ViewScripts явно ссылаются на ваш класс Form, действуют как "подвид" и позволяют вам управлять макетом каждого элемента. Примеры использования ViewScripts в прошлом были несколько трудными, но я постараюсь сделать что-то полезное.
Сначала переопределите loadDefaultDecorators в вашем классе формы:
public function loadDefaultDecorators() {
$this->setDecorators(
array(
array('ViewScript',
array('viewScript' => 'foo/bar.phtml')
)
)
);
}
Это будет ссылка на ViewScript с именем bar.phtml, расположенный в /views/scripts/foo. Обратите внимание на различия в регистре "ViewScript" и "viewScript" выше.
Затем вам нужно будет настроить декораторы, применяемые к каждому элементу, чтобы они отображались, но без раздражающих оберток dt/dd. Например:
$baz = new Zend_Form_Element_Text('bazInput');
$baz->setDecorators(array('ViewHelper','Errors'));
Наконец, вам нужно будет создать свой ViewScript, например:
<form method="post" action="<?php echo $this-element->getAction() ?>">
<table>
<tr>
<td><label for="bazInput">Baz:</label></td>
<td><?php echo $this->element->bazInput ?></td>
</tr>
</table>
<input type="submit" value="Submit Form" />
</form>
Очевидно, что это очень простой пример, но он иллюстрирует, как ссылаться на элементы формы и форматировать действие.
Затем в вашем представлении просто укажите и выведите форму, как обычно. Таким образом, вы можете иметь гораздо более тонкий контроль над макетами форм - включить легко добавлять Javascript.
Я считаю, что этот подход решает оба ваших требования: вы можете создавать формы в простом HTML и по-прежнему пользоваться механизмом проверки формы Zend.
Ответ 2
Я использовал как можно больше компонентов Zend за последние 10 месяцев, в большом проекте, а Zend_Form была самой большой болью в ***. Формы медленны, чтобы сделать, и трудно сделать красивыми. Даже не заводи меня на подформы. Я увидел интересную статью под названием " масштабирование zend_form", но, похоже, она не очень помогла в скорости рендеринга: (
Я думаю о том, чтобы все мои формы использовали прямой HTML в представлении и только с помощью Zend_Form выполняли проверку и фильтрацию (а не рендеринг). Либо это, либо я просто буду использовать Zend_Validate и Zend_Filter, без аспект формы вообще.
Инструмент - это только инструмент, если он вам помогает. В противном случае это просто помеха.
Ответ 3
Вот что я узнал с Zend_Form:
Позвольте ему сделать это, и это сэкономит вам тонну строк кода в долгосрочной перспективе.
Компромисс заключается в том, что вы создаете больше CSS, чтобы отображать вещи так, как вы хотите. Помните, что любой элемент HTML может быть стилизован, чтобы выглядеть как что угодно. По умолчанию Zend_Form дает вам множество селекторов CSS, чтобы получить конкретный (или широкий), как вам нужно. Я еще не видел случая, когда я не мог работать с декораторами по умолчанию, чтобы именно то, что я хотел, чтобы они были.
Конечно, у меня большой, уродливый CSS файл, но, по моему опыту, в любом случае это, скорее всего, большой, уродливый CSS файл. Я беру компромисс, не беспокоясь о кодировании/валидации/фильтрации/специфике формы приложения и т.д., Но имея дело с некоторыми особо стилизованными элементами в файле CSS.
Совет, если вы решите пойти по этому маршруту: убедитесь, что вы используете стиль CSS reset script
Ответ 4
Вот несколько декораторов, которые я использую в своих проектах, используя Zend Form. Эти, я считаю, достаточно простые, чтобы понять.
$stdRowDec = array('ViewHelper', 'Description', 'Errors', array(array('data'=>'HtmlTag'), array('tag' => 'td', 'width' => '200')), array('Label', array('escape' => false, 'class' => 'zfFormLabel', 'tag' => 'td')), array(array('row'=>'HtmlTag'), array('tag'=>'tr')));
$startRowDec = array('ViewHelper', 'Description', 'Errors', array(array('data'=>'HtmlTag'), array('tag' => 'td')), array('Label', array('escape' => false, 'tag' => 'td', 'class' => 'zfFormLabel')), array(array('row'=>'HtmlTag'), array('tag'=>'tr', 'openOnly'=>true)));
$startRowOpenOnlyDec = array('ViewHelper', 'Description', 'Errors', array(array('data'=>'HtmlTag'), array('tag' => 'td', 'openOnly'=>true)), array('Label', array('escape' => false, 'class' => 'zfFormLabel', 'tag' => 'td')), array(array('row'=>'HtmlTag'), array('tag'=>'tr', 'openOnly'=>true)));
$midRowDec = array('ViewHelper', 'Description', 'Errors', array(array('data'=>'HtmlTag'), array('tag' => 'td')),array('Label', array('escape' => false, 'class' => 'zfFormLabel', 'tag' => 'td')));
$midRowCloseOnlyDec = array('ViewHelper', 'Description', 'Errors', array(array('data'=>'HtmlTag'), array('tag' => 'td', 'closeOnly'=>'true')),array('Label', array('escape' => false, 'class' => 'zfFormLabel', 'tag' => 'td')));
$midRowCloseOnlyNoLabelDec = array('ViewHelper', 'Description', 'Errors', array(array('data'=>'HtmlTag'), array('tag' => 'td', 'closeOnly'=>'true')));
$endRowDec = array('ViewHelper', 'Description', 'Errors', array(array('data'=>'HtmlTag'), array('tag' => 'td')), array('Label', array('escape' => false, 'class' => 'zfFormLabel', 'tag' => 'td')), array(array('row'=>'HtmlTag'), array('tag'=>'tr', 'closeOnly'=>'true')));
$endRowCloseOnlyNoLabelDec = array('ViewHelper', 'Description', 'Errors', array(array('data'=>'HtmlTag'), array('tag' => 'td', 'closeOnly'=>'true')), array(array('row'=>'HtmlTag'), array('tag'=>'tr', 'closeOnly' => 'true')));
$buttonEndRowDec = array('ViewHelper', 'Description', 'Errors', array(array('data'=>'HtmlTag'), array('tag' => 'td', 'colspan'=>'2', 'align'=>'center')), array(array('row'=>'HtmlTag'), array('tag'=>'tr', 'closeOnly'=>'true')));
$buttonDecorators = array('ViewHelper', array(array('data' => 'HtmlTag'), array('tag' => 'td', 'class' => 'element')), array(array('label' => 'HtmlTag'), array('tag' => 'td', 'placement' => 'prepend')), array(array('row' => 'HtmlTag'), array('tag' => 'tr')), );
Ответ 5
Я использую Zend Framework около года, и я использовал только Zend_Form
для одного из моих проектов (первого). Я отказался от Zend_Form
после того, как потратил все 15 минут, пытаясь поместить ссылку "Отменить".
Я действительно люблю интеграцию.
Теперь я использую простые формы HTML и использую Zend_Filter_Input
в модели (Zend_Db_Table
в большинстве случаев, но мне пришлось добавить уровень сервиса в мой последний проект).
Пример фрагмента кода контроллера с использованием ZFI в модели. Обработка ошибок и общие методы проверки находятся в подклассе Zend_Db_Table
, и мои классы расширяют его.
Помощник вида форматирует массив сообщений об ошибках.
if ($this->_request->isPost()) {
$data = $this->_request->getPost();
$event = new Default_Model_DbTable_Event();
$event->createRow($data)->save();
if ($event->hasErrors()) {
$this->view->errors = $event->getErrorMessages();
$this->view->event = $data;
} else {
$this->_redirect('events');
}
}
Ответ 6
Если вы хотите валидаторы и фильтры без форм: Zend_Filter_Input
22,5. Zend_Filter_Input
Zend_Filter_Input
обеспечивает декларативный интерфейс для связывания несколько фильтров и валидаторов, применяются их сборам данных и извлекать входные значения после того, как они обрабатывались фильтрами и валидаторы. Значения возвращаются в экранированный формат по умолчанию для безопасного Выход HTML.
Хотя - Мое личное предложение - научиться создавать пользовательские декораторы и просматривать помощники. Zend_Form
очень мощный, и у меня никогда не было проблем с позицией/украшением вещей. Даже при создании сложной таблицы разрешений и автоматической генерации столбцов и строк с помощью jQuery - я нашел интерфейсы Zend_Form
для экономии времени. Если у вас есть конкретный вопрос о том, как подойти к украшению, я с радостью помогу. Откройте новый вопрос и прокомментируйте его здесь или что-то в этом роде.
Ответ 7
Я второй, о чем говорил lo_fye. По моему опыту Zend Forms неуклюжи и не продуманы.
Решение, которое я нашел наиболее простым и гибким, состоит в том, чтобы создать два файла формы: 1. класс формы, который инициализирует элементы формы, затем представление script для отображения элементов формы. В моем классе формы я отключу все декораторы, минус фактический элемент формы. например.:
- > removeDecorator ( 'HtmlTag')
- > removeDecorator ( 'DtDdWrapper')
- > removeDecorator ( 'Этикетка')
- > removeDecorator ( 'ошибки');
Затем в конце конструктора, который инициализирует элементы формы, передайте представление script: $this- > setDecorators (array (array ('ViewScript', array ('viewScript' = > 'path/to/script_form.phtml '))));
В представлении script я форматирую форму точно так, как мне нравится, тогда, когда поле ввода (например,) будет просто отображать этот элемент: $this- > element- > form_element_id. И обратите внимание, что я удаляю декорации ошибок и просто хватаю стек ошибок и показываю, как я думаю, что это должно быть.
Недостатком является то, что вы создадите представление script для каждой формы или создадите какую-то систему многократного использования, поэтому выполните дополнительную работу. Но, в конце концов, гораздо проще создавать формы, подходящие в вашем макете, imo.
Ответ 8
Вы можете использовать Zend Form и генерировать HTML самостоятельно:) Вам просто нужно отслеживать изменения и вызывать элементы формы одинаково в HTML и ZF:)
Ответ 9
Короткий ответ. Используйте Zend_Form только для проверки и фильтрации и используйте ваши простые старые сценарии представления, чтобы визуализировать форму так, как вы хотите.
Длинный ответ. Я пришел к выводу, что не стоит использовать Zend_Form для генерации HTML-формы. По крайней мере, в компании я работаю. Но почему?
Это просто, я не хочу создавать класс (или использовать хак) только для "спокойного" добавления ссылки внутри div внутри моей формы. Я не хочу создавать несколько декораторов, чтобы добавить функциональность, которую можно легко добавить с помощью простого HTML, и, самое главное, дизайнеры, которые работают с нами, не хотят редактировать один (или два или более) класс [es] только для сделать свою работу.
Мы продолжаем использовать Zend_Form, но только для проверки и фильтрации наших форм. И не генерировать их.
Я знаю, что многие не согласятся с моими аргументами, но это только мнение того, у кого были бессонные ночи, проведенные благодаря Zend_Fom.
Ответ 10
Изменить/Комментировать верхний ответ by @Cal Jacobson.
Невозможно отредактировать, так как для изменения недостаточно символов, невозможно прокомментировать из-за недостаточной репутации, но...
$this-element->getAction()
должен быть
$this->element->getAction()
Я уверен, что OP это знает, но исправление позволит избежать ошибки при попытке напрямую использовать код в ответе.