Лучшие способы использования Zend_Form в Zend MVC

При использовании Zend_Form я создаю множество методов контроллера, которые выглядят так:

function editPersonAction()
{
   $model = $this->getPersonModel();
   $form = $this->getPersonEditForm();
   if ($this->getRequest()->isPost() {
       $data = $this->getRequest()->getPost();
       //$form->populate($data); [removed in edit]

       if ($form->isValid($data)) {
           $data = $form->getValues();
           $model->setFromArray($data);
           // code to save model then decide which page to redirect to
       }
   } else {
       $form->populate($model->toArray());
   }
   $this->view->form = $form;
}

Большая часть этого кода всегда одна и та же, и я уверен, что есть лучшие способы сделать это. Какие еще шаблоны люди используют с Zend_Form, чтобы сократить количество используемого стандартного кода?


person Paul Stone    schedule 03.07.2009    source источник


Ответы (3)


Мне нравится сохранять как можно больше в моделях

function editPersonAction()
{
   $model = $this->getPersonModel();

   if ($this->getRequest()->isPost() {
       $data = $this->getRequest()->getPost();

       if ($model->validateForm($data)) {
           // code to save model then decide which page to redirect to
       } else {
          // error management
       } 
   } 

   $this->view->form = $model->getForm();
}

Итак, в модели у меня было бы:

public function validateForm(array $data)
{    
    $form = $this->getForm();

    if($form->isValid($data))
    {
        // code to save model state

        return true;
    } else {
        return false;
    }
}

public function getForm($instance = 'default') {
   if (!isset($this->_forms[$instance])) {
       $this->_forms[$instance] = new Your_Form_Class();           
       $this->_forms[$instance]->populate($this->toArray());
   }

   return $this->_forms[$instance];
}

Кроме того, вы можете добавить эти методы в абстрактную модель, которую будут расширять все ваши модели приложений, а затем перезаписывать их только тогда, когда вам нужно сделать что-то особенное.

person Gabriel Solomon    schedule 03.07.2009
comment
Ваше использование хранения объектов формы в виде массива является проницательным. Это то, что я мог бы использовать в своих моделях, поскольку в настоящее время у меня есть только геттеры для определенных форм. +1 - person Kieran Hall; 03.07.2009

Действительно ли необходима $form->populate()? Недопустимые формы IIRC будут заполняться автоматически.

person Karsten    schedule 03.07.2009
comment
спасибо, я удалил первую $form-›populate(). Второй по-прежнему необходим для первоначального заполнения формы из базы данных. - person Paul Stone; 03.07.2009

Честно говоря, в моих контроллерах тоже есть похожие действия. Одна вещь, которую я делаю, чтобы уменьшить вес в контроллере, и по соглашению, это проверка проверки в модели. Я также вызываю объект формы из модели, чтобы облегчить это (возможно, вы уже делаете это с помощью вашего метода getPersonEditForm в вашем контроллере. Поэтому, если бы я написал ваше действие, оно выглядело бы так:

function editPersonAction()
{
   $model = $this->getPersonModel();
   $form  = $this->getPersonEditForm();

   if($this->getRequest()->isPost()) 
   {
       if($model->setFromArray($this->getRequest()->getPost()))
       {
           // code to decide which page to redirect to
       }
   }
   else
   {
       $form->populate($model->toArray());
   }

   $this->view->form = $form;
}

Итак, в методе модели setFromArray у меня было бы:

public function setFromArray(array $data)
{
    $form = $this->getRegistrationForm();

    if($form->isValid($data))
    {
        // code to save model state

        return true;
    }
    else
    {
        return false;
    }
}

По общему признанию, это не намного более лаконично, чем ваш существующий подход, и я, как и вы, часто чувствую, что его можно было бы лучше абстрагировать.

person Kieran Hall    schedule 03.07.2009
comment
я бы назвал метод проверки моделей или что-то подобное, поскольку setFromArray не кажется правильным определением, по крайней мере, с моей точки зрения - person Gabriel Solomon; 03.07.2009
comment
Я согласен с тем, что setFromArray не звучит как хорошее имя метода, однако проверка хуже, поскольку она не описывает, что происходит с данными (только то, что она должна быть сначала проверена). Большинство методов моей модели начинаются с «получить», «добавить», «редактировать» или «удалить», чтобы дать четкое представление о том, что нужно делать с данными. - person Kieran Hall; 03.07.2009