Подтвердить что ты не робот

Zend Framework формы, декораторы и проверки: должен ли я вернуться к простому HTML?

В настоящее время я работаю над довольно большим приложением, которое содержит множество форм.

До этого момента я всегда писал свои формы вручную и писал свою собственную логику проверки, но я решил, что пришло время использовать Zend_Form и встроенные процедуры проверки.

Тем не менее, я продолжаю сталкиваться с все более и более проблемами, связанными с (отсутствием) гибкости, вызванной Zend_Form_Decorator. Простые задачи, такие как добавление дополнительной кнопки в один элемент ввода, становятся невероятно трудными задачами.

Теперь я понял, что серьезно рассматриваю возможность сброса Zend_Form_Element + Zend_Form_Decorator полностью, но я не хочу потерять отличные варианты проверки.

В принципе, я хочу лучшее из обоих миров:

  • Запись форм так, как видит их конечный пользователь: в обычном HTML
  • Легко добавлять проверки на стороне сервера для формирования полей, не нарушая слишком много стандартного поведения ZF

Возможное решение, которое я рассматриваю, заключается в написании форм как на стороне сервера, так и в представлениях. Это позволило бы мне легко проверить мои собственные формы, но (в моих глазах довольно большой) недостаток состоит в том, что каждая форма должна быть определена дважды, что просто кажется неправильным.

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

Я очень хотел бы услышать ваши точки зрения.

4b9b3361

Ответ 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 это знает, но исправление позволит избежать ошибки при попытке напрямую использовать код в ответе.