4

Zend_Form コンポーネントを使用してフォームを作成しようとしていますが、要素の数が異なります。各 Zend_Form 要素の情報 (名前、オプション、バリデーター、フィルターなど) はデータベースに保存されます。

私が取り組んでいるアプリケーションは、さまざまな数の質問を含む調査を構築することで構成されています。各質問は、さまざまな回答の配列に関連付けられています。最終的に私の目標は、サーバー側で動的にラジオ/チェックボックス ボタンの配列を構築することです。

フォームをきれいに生成する方法を探していますが、フォーム内にモデルをロードする最良の方法がわかりません。モデルをコントローラーにロードしてから (どういうわけか、パラメーターを介して) 直接フォームに渡す必要がありますか、それともフォームの init() メソッド内でモデルをロードする方がよいでしょうか? フォーム クラス内、コントローラー内、またはモデル内のどこにロジックを配置するのが最適ですか?

私の考えは、データベース内のフォーム要素のプロパティ (名前、ルール、フィルターなど) を取得し、反復して最終的にフォームをレンダリングすることです。このアプローチについてどう思いますか?最終的に、今回は AJAX と JavaScript ライブラリ (jQuery など) を使用して、要素が動的に追加されます (クライアント側)。

Google で見つけた便利なリンクをいくつか紹介しますが、それらはすべて私の質問とは少し異なる質問に答えていると思います。

動的フォームの構築時、サーバー側:

クライアント側で AJAX 処理を使用して動的フォームを構築する場合:

4

2 に答える 2

4

考えられる解決策を見つけたと思います。これには、ZendForm要素の配列をZendForm :: __ Construct()メソッドに渡すことが含まます。コンストラクターはオプションの配列を取り、そのうちの1つは「要素」と呼ばれます。ZendFrameworkライブラリ内のソースコードをご覧ください。

コントローラー内にbuildSurveyForm()という新しいプライベートメソッドをコーディングしました。注:パラメーターとして渡されるオブジェクトは、データベース内のいくつかのテーブル(調査、質問、回答など)からデータをフェッチする、半ダースのJOINステートメントを含む巨大なSQLクエリから構築されます。このクラスのパブリック属性の1つは、オブジェクトとして格納された質問の配列で構成されます(パブリックメソッド/属性なども含まれます)。答えも同じです。これらのクラスを構築するためのコードは非常に簡単で、ここではトピックから外れています。

サーベイコントローラ内のコードは次のとおりです。私はそれをより明確にするために数行をコピー/貼り付けおよび編集/ドロップしました:

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クラスには、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 に答える