4

我正在尝试使用 Zend_Form 组件构建一个表单,但元素的数量会有所不同。每个 Zend_Form 元素的信息都存储在数据库中(名称、选项、验证器、过滤器等)。

我正在处理的应用程序包括构建包含不同数量问题的调查。每个问题都与不同的答案数组相关联。最终,我的目标是在服务器端动态地构建单选/复选框按钮数组。

我正在寻找一种生成表单的漂亮方法,但我不确定在表单中加载模型的最佳方法。是否应该将模型加载到控制器中,然后直接传递(不知何故,通过参数?)到表单,还是在 Form init() 方法中加载模型更好?放置逻辑的最佳位置在哪里,应该在表单类中,还是在控制器中,还是在模型中?

我的想法是在数据库中获取表单元素属性(名称、规则、过滤器等),然后迭代并最终呈现表单。您如何看待这种方法?最终,元素将被动态添加(客户端),这一次,使用 AJAX 和 JavaScript 库(如 jQuery)。

以下是我通过谷歌找到的几个有用的链接,但我认为它们都回答了一个与我的问题略有不同的问题:

在构建动态表单时,服务器端:

在使用 AJAX 处理构建客户端的动态表单时:

4

2 回答 2

4

我想我找到了一个可能的解决方案,它涉及将Zend Form 元素数组传递给Zend Form::__construct()方法。构造函数采用一组选项,其中一个称为“元素”。查看 Zend Framework 库中的源代码。

我在控制器中编写了一个新的私有方法,称为 buildSurveyForm()。注意:作为参数传递的对象是由一个带有六个 JOIN 语句的巨大 SQL 查询构建的,从数据库中的几个表(调查、问题、答案等)中获取数据。此类的公共属性之一由一系列问题组成,存储为对象(也具有公共方法/属性等)。答案也一样。用于构建这些类的代码非常简单,并且不在此处讨论。

这是调查控制器中的代码。我复制/粘贴和编辑/删除了几行以使其更清晰:

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,
    ));
}

向表单元素添加过滤器、验证器和装饰器现在很简单。我的建议有点脏,但我认为它可以完成工作。如果我发现更优雅的东西,我会添加一个新的提案。随意发布不同的答案/解决方案。

于 2009-03-12T22:52:55.867 回答
2

你可以扩展 Zend_Form。

Zend 形式不是逻辑的好地方,只有形式表示。

因此,使用控制器中的模型加载所有需要的元素,并将它们作为参数传递给构造器中的表单。

于 2009-03-08T22:56:05.840 回答