Загрузка моделей в Zend_Form с помощью Zend Framework
-
05-07-2019 - |
Вопрос
Я пытаюсь создать форму, используя компонент Zend_Form, но количество элементов варьируется.Информация для каждого элемента Zend_Form хранится в базе данных (имя, параметры, средства проверки, фильтры и т.д.).
Приложение, над которым я работаю, состоит из опросов зданий, которые содержат различное количество вопросов.Каждый вопрос связан с различными массивами ответов.В конечном счете, моя цель - динамически создавать массивы кнопок радио / чекбокса на стороне сервера.
Я ищу красивый способ сгенерировать свою форму, но я не уверен в лучшем способе загрузки модели в форму.Должна ли модель загружаться в контроллер, а затем передаваться (каким-то образом, через параметр?) непосредственно в форму, или лучше загрузить модель с помощью метода Form init()?Где лучше всего разместить логику, должна ли она быть внутри класса form, или внутри контроллера, или внутри модели?
Моя идея состоит в том, чтобы извлечь свойства элемента формы (имя, правила, фильтры и т.д.) Из базы данных, затем выполнить итерацию и, наконец, отобразить форму.Что вы думаете о таком подходе?В конечном счете элементы будут добавлены динамически (на стороне клиента), на этот раз с использованием AJAX и библиотеки JavaScript (такой как jQuery).
Вот пара полезных ссылок, которые я нашел через Google, но я думаю, что все они отвечают на несколько иной вопрос, чем мой:
О создании динамических форм на стороне сервера:
- http://framework.zend.com/wiki/display/ZFPROP/Zend_Form+generation+from+models+-+Jani+Hartikainen
- http://weierophinney.net/matthew/archives/200-Using-Zend_Form-in-Your-Models.html
- http://codeutopia.net/blog/2009/01/07/another-idea-for-using-models-with-forms/
О создании динамических форм на стороне клиента с обработкой AJAX:
Решение
Вы могли бы расширить Zend_Form .
Zend form - неподходящее место для логики, только для представления формы.
Итак, загрузите все необходимые элементы, используя model в контроллере, и передайте их в форму в конструкторе в качестве параметров.
Другие советы
Я думаю, что я нашел возможное решение, оно включает в себя передачу массива Элементы формы Zend к тому Форма Zend::__construct() способ.Конструктор принимает массив параметров, один из которых называется "элементы".Взгляните на исходный код в библиотеке Zend Framework.
Я закодировал новый закрытый метод внутри контроллера, называемый buildSurveyForm().Примечание :объект, передаваемый в качестве параметра, создается на основе огромного SQL-запроса с полудюжиной операторов JOIN, извлекающих данные из нескольких таблиц (опросы, вопросы, ответы и т.д.) в базе данных.Один из общедоступных атрибутов для этого класса состоит из массива вопросов, хранящихся в виде объектов (также с общедоступными методами / атрибутами и т.д.).То же самое и с ответами.Код для создания этих классов довольно тривиален и не соответствует теме здесь.
Вот код внутри контроллера опроса.Я скопировал / вставил и отредактировал / убрал несколько строк, чтобы сделать это намного понятнее :
private function buildSurveyForm(MyApp_Object_Survey $survey)
{
foreach ($survey->questions as $question)
{
$element = new Zend_Form_Element_MultiCheckbox($question->order);
$element->addMultiOptions($question->getAnswersLabels());
$element->setName($question->order);
$element->setLabel($question->title);
$elements[] = $element;
}
// Here's the trick :
$formOptions = array('elements' => $elements);
$surveyForm = new MyApp_Survey_Form($formOptions);
$urlHelper = $this->_helper->getHelper('url');
$surveyForm->setAction($urlHelper->url(array(
'controller' => 'survey',
'action' => 'vote'),
'default'
));
$surveyForm->setMethod('post');
$this->_forms['survey'] = $surveyForm;
return $this->_forms['survey'];
}
В Форма опроса MyApp класс содержит только кнопку Отправки в методе init().Динамически сгенерированные элементы с приведенным выше кодом добавляются ПЕРЕД этой кнопкой отправки (что неожиданно, но полезно).Этот класс просто расширяет Zend_Form.
Затем, в рамках действия контроллера опроса / просмотра :
public function viewAction()
{
$surveyModel = $this->_model['survey'];
$survey = $surveyModel->getFullSurvey($this->_getParam('id'));
$survey = new MyApp_Object_Survey($survey);
// Calls above private method :
$surveyForm = $this->buildSurveyForm($survey);
$this->view->assign(array(
'surveyForm' => $surveyForm,
));
}
Добавление фильтров, валидаторов и декораторов к элементам формы теперь стало тривиальным.Мое предложение немного грязновато, но я думаю, что оно выполняет свою работу.Я добавлю новое предложение, если найду что-то более элегантное.Не стесняйтесь публиковать разные ответы / решения.