Zend Frameworkを使用してZend_Formにモデルをロードする
-
05-07-2019 - |
質問
Zend_Formコンポーネントを使用してフォームを作成しようとしていますが、要素の数は異なります。各Zend_Form要素の情報はデータベースに保存されます(名前、オプション、バリデーター、フィルターなど)。
私が取り組んでいるアプリケーションは、さまざまな数の質問を含む建物調査で構成されています。各質問は、回答の異なる配列に関連付けられています。最終的に私の目標は、ラジオ/チェックボックスボタンの配列をサーバー側で動的に構築することです。
フォームを生成するきれいな方法を探していますが、フォーム内にモデルをロードする最良の方法がわかりません。モデルをコントローラーにロードしてから(何らかの方法でパラメーターを介して)フォームに直接渡すか、Form init()メソッド内でモデルをロードする方がよいでしょうか?ロジックを配置するのに最適な場所はどこですか、フォームクラス内、コントローラー内、またはモデル内にあるべきですか?
データベース内のフォーム要素のプロパティ(名前、ルール、フィルターなど)を取得し、繰り返して最終的にフォームをレンダリングするのが私の考えです。このアプローチについてどう思いますか?最終的に、要素は動的に追加されます(クライアント側)。今回は、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フォームはロジックには適していません。フォーム表現のみです。
したがって、コントローラーのモデルを使用して必要なすべての要素をロードし、それらをパラメーターとしてコンストラクターのフォームに渡します。
他のヒント
可能な解決策を見つけたと思います。これには、 Zend Form要素の配列を Zend Form :: __ construct()メソッドに渡すことが含まれます。コンストラクターはオプションの配列を取り、そのうちの1つは" elements "と呼ばれます。 Zend Frameworkライブラリ内のソースコードをご覧ください。
コントローラ内でbuildSurveyForm()と呼ばれる新しいプライベートメソッドをコーディングしました。注:パラメータとして渡されるオブジェクトは、データベース内のいくつかのテーブル(調査、質問、回答など)からデータを取得する、6個以上の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()メソッド内にSubmitボタンのみが含まれています。上記のコードで動的に生成された要素は、この送信ボタンの前に追加されます(予想外ですが、便利です)。このクラスは単に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,
));
}
フィルター、バリデーター、およびデコレーターをフォーム要素に追加するのは簡単です。私の提案は少し汚いですが、仕事を成し遂げると思います。もっとエレガントなものが見つかったら、新しい提案を追加します。さまざまな回答/解決策を投稿してください。