Загрузка моделей в Zend_Form с использованием Zend Framework - PullRequest
4 голосов
/ 09 марта 2009

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

Приложение, над которым я работаю, состоит из построения опросов, которые содержат различное количество вопросов. Каждый вопрос связан с различными массивами ответов. В конечном итоге моя цель состоит в том, чтобы динамически создавать массивы кнопок радио / флажков на стороне сервера.

Я ищу красивый способ создания формы, но я не уверен, что лучше всего загрузить модель внутри формы. Должна ли модель загружаться в контроллер и затем передаваться (каким-либо образом через параметр?) Непосредственно в форму, или лучше загрузить модель в методе init init ()? Где лучше всего разместить логику, должна ли она быть внутри класса формы, или внутри контроллера, или внутри модели?

Моя идея - получить свойства элемента формы (имя, правила, фильтры и т. Д.) В базе данных, затем выполнить итерацию и, наконец, отобразить форму. Что вы думаете об этом подходе? В конечном итоге, элементы будут динамически добавляться (на стороне клиента), на этот раз с использованием AJAX и библиотеки JavaScript (например, jQuery).

Вот пара полезных ссылок, которые я нашел через Google, но я думаю, что они все отвечают на несколько иной вопрос, чем мой:

При построении динамических форм на стороне сервера:

При построении динамических форм на стороне клиента с обработкой AJAX:

Ответы [ 2 ]

4 голосов
/ 13 марта 2009

Я думаю, что нашел возможное решение, оно включает передачу массива элементов Zend Form в метод Zend Form :: __ construct () . Конструктор принимает массив параметров, один из которых называется " elements ". Посмотрите на исходный код в библиотеке 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 Survey Form содержит только кнопку Submit в методе 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,
    ));
}

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

2 голосов
/ 09 марта 2009

Вы можете расширить Zend_Form.

Зенд форма не подходит для логики, только представление формы.

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

...