Zend Form: Как мне заставить его подчиниться моей воле? - PullRequest
42 голосов
/ 11 февраля 2009

Я много раз читал руководство, я просмотрел посты, предлагаемые Google по этому вопросу, я даже купил пару книг, посвященных ZF. Теперь, почему я все еще в замешательстве?

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

У кого-нибудь есть простой способ достижения такого рода вещей? Что-то, что заставляет меня чувствовать, что фреймворк экономит мне время, а не стоит? Я мог отказаться от Zend Form ... создать свою собственную форму, чтобы ее действие попадало на страницу, чтобы проверить и обработать опубликованные данные, и я мог бы делать это примерно так быстро, как я могу печатать, но я действительно хочу "получить" это и иметь возможность использовать его так, как это было задумано.

Какой совет? Какие-нибудь простые "как сделать" для пользовательских кнопок, прикольных макетов и базовых (или, точнее, продвинутых, поскольку есть тонны базовых учебных пособий, пропускающих более сложные вопросы) "выполнения задач" с помощью Zend Form?

Ответы [ 14 ]

26 голосов
/ 08 марта 2009

Совет Барретта Конрада - это то, что я бы предложил. Также имейте в виду, что вам не нужно использовать объект формы для отображения вашей формы.

Одна вещь, которую вы можете сделать, это создать форму в вашем скрипте вида, которая имеет элементы с тем же именем, что и у класса формы.

Ваша HTML-форма:

<form action="/login/" method="post">
<fieldset>
    <label for="username">Username:</label>
    <input type="text" size="10" name="username" />
    <label for="password">Password:</label>
    <input type="password" size="10" name="password" />
    <input type="submit" />
</fieldset>
</form>

Ваш класс:

class LoginForm extends Zend_Form
{
    public function init()
    {
        $username = $this->createElement('text','username');
        $username->setRequired(true);
        $this->addElement($username);

        $password = $this->createElement('password','password');
        $password->setRequired(true);
        $this->addElement($password);        
    }
}

Ваш класс формы отражает вашу HTML-форму, каждый элемент в вашем классе имеет свои валидаторы и требования. Вернувшись в свое действие, вы можете создать экземпляр класса вашей формы и проверить ваши записи / получить vars по этой форме:

$form = new LoginForm();
if ($this->_request->isPost()) {
    if ($form->isValid($this->_request->getParams())) {
        // do whatever you need to do
    } else {
        $this->view->errors = $form->getMessages();
    }
}

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

Это базовый пример, но он позволяет вам полностью контролировать представление вашей формы, не тратя время на то, чтобы научиться использовать декораторы. На мой взгляд, большая часть Zend_Form заключается в его свойствах проверки и фильтрации. Это дает вам эту силу. Основным недостатком такого решения является то, что HTML-форма вашего скрипта представления может стать не синхронизированной с вашим классом формы.

11 голосов
/ 20 марта 2011

Визуализируйте каждый элемент индивидуально, например

<!-- view script here -->
<form method="POST">
Name: <?php echo $this->myForm->getElement('name')->render(); ?>
some other text between the fields
Birthdate: <?php echo $this->myForm->getElement('birthdate')->render(); ?>
<input type="submit" />
</form>

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

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

9 голосов
/ 08 мая 2009
5 голосов
/ 11 февраля 2009

В настоящее время у нас есть новый и блестящий Zend\Form, который даже более сложный, чем старый компонент, но также гораздо более управляемый, инкапсулированный и мощный. Итак, то, что я сказал ниже, не относится. Новый компонент ИМХО огромное улучшение, потому что он ...

  • ... дает вам полный контроль над тем, как вы хотите визуализировать форму, вам нужно написать немного больше кода для просмотра, но оно того стоит
  • ... максимально разделяет данные, логику и представление
  • ... использует элементы формы HTML5
  • ... дает вам много вариантов, как вы хотите соединить ваши формы, например, гидратация, аннотации и т. д.

Старый ответ относительно Zend_Form

Не могу помочь, наверное, потому что у меня точно такая же проблема. Я думаю, что декораторы Zend_Form - это мощные, но, безусловно, наименее дружественные к программистам и неинтуитивные части ZF, которые я видел до сих пор, и я использовал большую часть ZF в различных проектах.

Тем не менее, я могу дать только несколько советов из моего опыта:

  • фильтры просты в использовании без использования формы
  • большинство, если не все, чего вы хотите достичь, выполняется с помощью декораторов
  • Я начал с маленьких форм и добавил что-то по кусочкам, но я не получаю некоторые вещи, которые я делаю в некоторых из моих форм, потому что результат основан на методе проб и ошибок (в основном с декораторами)
  • У меня есть информация из списка рассылки Zend, которую я не смог найти нигде в Интернете

Из соответствующих вопросов, приведенных справа, очевидно, что отсутствует исчерпывающая документация для Zend_Form, особенно учитывая ее неинтуитивную природу. Мне бы очень хотелось, чтобы ребята из ZF сделали что-то с этим так же, как мне нравится Zend Framework.

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


или в качестве альтернативы вы можете использовать трюки с умом джедая конечно!

4 голосов
/ 11 февраля 2009

Добавить к сказанному:

Не бойтесь декораторов, вы будете их много использовать, если решите придерживаться Zend_Form. Это довольно просто, как только вы «получите», к сожалению, документы слабы, и играть с ним - почти единственный способ добраться до него.

Декораторы ViewScript и ViewHelper дают вам много возможностей.

Не бойтесь покопаться в источнике для различных существующих декораторов и посмотреть, как они работают (я получил достаточно глубокое понимание, сравнивая оригинальные декораторы с додзё).

Я думаю, что Шон предлагал, что вам не нужно вызывать form-> render, вы можете использовать что-то подобное в вашем скрипте просмотра.

 <someHtmlThingy name="blah" value="<?php echo $this->formInstance->getElement('whatever')->getValue(); ?>" />

Я работал над одним проектом (до Zend_Form), где мы создавали наборы валидаторов и использовали стандартные сценарии просмотра на всем протяжении. Это было немного больше работы (слежение за сообщениями об ошибках и т.п.), но не чрезмерно по сравнению с созданием элементов с Zend_Form.

3 голосов
/ 29 июня 2009

Если вы просто хотите добавить произвольную разметку до или после элементов формы без использования декоратора ViewScript, вы можете использовать мой декоратор AnyMarkup: http://www.zfsnippets.com/snippets/view/id/62

Например, вот как вы должны добавить в поле ввода изображение внутри тега-обертки (для правильной установки необходимо указать пути для автозагрузки):

$form->addElement('text', 'my_field', array(
  'label' => 'Enter Info:',
  'decorators' => array(
    'ViewHelper',
    array('AnyMarkup', array(
      'markup' => '<span class="imgwrapper"&gt'.
        '<img src="info.png" alt="info icon"/></span>'),
      'placement' => 'prepend'
    ),
    'HtmlTag',
    'Label'
  )
);
2 голосов
/ 11 февраля 2009

whycantitbemore, чем 25c упомянул их выше, но ViewScripts дают вам чрезвычайно детальный контроль для отрисовки форм. Zend_Form предназначен для быстрой работы, поэтому он принимает множество значений по умолчанию, таких как стандартные декораторы, и упорядочивает элемент так, как они были добавлены в объект формы. С помощью ViewScript вы можете пропустить большую часть этого и разместить все свои элементы так, как вам хотелось бы, в обычном HTML.

Не пренебрегайте концепцией декораторов полностью. Они разрабатывают отдельные элементы, даже если они используются в ViewScript позже. Например, вы можете использовать их для сообщений об ошибках, как предлагали другие.

Если у вас очень сложная форма с несколькими точками данных с похожими действиями (например, список пользователей с активными / неактивными кнопками и кнопкой удаления для каждого), вам следует рассмотреть Zend_Form_SubForm . В подчиненных формах могут использоваться ViewScripts точно так же, как в обычных формах, и если вы каскадируете форму с помощью ViewScript с подчиненными формами с их собственными ViewScripts, вы в конечном итоге получаете приятную логику и представление, которые намного мощнее, чем просто прямая форма.

2 голосов
/ 11 февраля 2009

К сожалению, более сложные проблемы пропускаются, потому что без реальной конкретной цели или цели очень сложно написать пример или практические рекомендации. Я потратил некоторое время на то, чтобы помочь другому разработчику в SO, который хотел изменить способ отображения скрытых элементов , но его случай был очень конкретным, поэтому было легче углубиться в детали.

Большинство более сложных задач действительно сводятся к расширению помощника по умолчанию для определенного типа поля. Например, у меня был проект, в котором я хотел применить класс «error» ко всем полям, которые не прошли проверку после отправки формы, вместо того, чтобы выписать текст ошибки проверки:

<label for="field">Label:</label>
<input type="text" name="field" id="field" class="error">

Это был довольно сложный процесс, потому что фактический элемент формы по умолчанию недоступен помощнику вида, поэтому помощник не может проверить, есть ли у элемента ошибка проверки. Итак, я пошел о следующем процессе:

  1. Мне нужно было создать помощника представления клиента для каждого типа поля, к которому я хотел применить класс «error». В нем я переопределил метод formXXX() и добавил проверку, чтобы убедиться, что в элементе произошла ошибка. Кроме того, я добавил метод setElement(), который декоратор мог вызывать для установки экземпляра элемента, чтобы мой помощник мог проверять наличие ошибок.
  2. Далее мне пришлось переопределить значение по умолчанию Zend_Form_Decorator_ViewHelper. В нем я получил доступ к представлению, создал экземпляр помощника для типа элемента формы и проверил наличие метода setElement(), который я создал в помощнике вида, установив его, если он существует. Делая это, я мог бы расширить некоторые типы элементов формы, а не другие, не разрушая весь скрипт.
  3. В моей функции init () для каждой формы мне пришлось добавить новый путь префикса элемента (addElementPrefixPath('My_Form_Decorator'), 'path/to/decorator')), который указывал на мой новый декоратор формы.
  4. Наконец, мне пришлось добавить вспомогательный путь к моему приложению, чтобы Zend Framework мог найти помощников, которых я создал в первом пункте: addHelperPath('/path/to/helpers', 'My_View_Helper');

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

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

2 голосов
/ 11 февраля 2009

Отказ от использования декораторов всей формы (т. Е. Печать отдельных элементов формы, а не просто использование стандартного помощника вида для обработки всего) - один из способов вернуть контроль.

Другой вариант - просто вручную закодировать форму и использовать ZF только для проверки и фильтрации.

1 голос
/ 18 ноября 2009

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

form->getSubform('subform'); 
foreach ($subform as $key => $value) {
//some markup and custom code here
    print $value;
//some markup and custom code here

}
?>

внутри цикла foreach, вы можете добавить разметку таблицы. Если вы правильно назвали ключи для строк таблицы, они должны совпадать с ключами формы. Вы можете даже использовать цикл, который захватывает соответствующую подчиненную форму по ключу или даже элемент по ключу. Вы можете пропустить цикл foreach, если знаете ключи, и просто сказать print $ subform ['somekey']; при условии, что вы установили основную форму, сказав $ form-> setIsArray (true); (не уверен, что эта последняя часть строго необходима, но для сложных форм она должна быть так или иначе установлена.

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

Надеюсь, это кому-нибудь пригодится!

...