Лучшие способы обработки формы записи в Zend Framework - PullRequest
3 голосов
/ 03 августа 2009

Когда вы в порядке с базовой формой записи, созданной по примеру с Tutorial, вы понимаете, что вам нужна более профессионально разработанная форма записи. Например. Я не хочу дублировать форму записи для одной и той же таблицы в областях пользователя и администратора.

1) Кто-нибудь использует какой-то механизм, возможно наследование, чтобы уменьшить дублирование почти одинаковых форм администратора и пользователя? Это обременительно или иногда лучше делать с копированием?

2) Кто-нибудь посчитал хорошей идеей создать базовый класс Record

  • , который может определить, что среди нескольких форм записей на этой странице, текущее сообщение адресовано именно этой форме записи
  • , который может организованно различать щелчки кнопок "Редактировать" и "Удалить".

3) Моя текущая практика включает в себя помещение всего кода конфигурации формы (декораторов, проверок, начальных значений) в конструктор, а обработку отправки формы помещают в отдельный метод ProcessSubmit () для освобождения контроллера от ненужного кода.

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

Ответы [ 2 ]

2 голосов
/ 05 августа 2009

Пара предложений:

Прежде всего - используйте функцию init() вместо конструкторов, чтобы добавить свои элементы, когда вы создаете подклассы формы. Функция init () происходит после установки параметров, которые вы передаете классу.

Второй - вместо того, чтобы создавать подклассы для вашей формы - вы можете просто установить «опцию», чтобы включить админ:

class My_Record_Form extends Zend_Form {
    protected $_record = null;
    public function setRecord($record) {
      $this->_record = $record;
    }

    public function getRecord() {
      if ($this->_record === null || (!$this->_record instanceOf My_Record)) {
        throw new Exception("Record not set - or not the right type");
      }
      return $this->_record;
    }

    protected $_admin = false;
    public function setAdmin($admin) {
      $this->_admin = $admin;
    }

    public function getAdmin() { return $this->_admin; }

    public function init() {
      $record = $this->getRecord();

      $this->addElement(......);
      $this->addElement(......);
      $this->addElement(......);

      if ($this->getAdmin()) {
        $this->addElement(.....);
      }

      $this->setDefaults($record->toArray());
    }

    public function process(array $data) {
      if ($this->isValid($data)) {
        $record = $this->getRecord();
        if (isset($this->delete) && $this->delete->getValue()) {
          // delete button was clicked
          $record->delete();
          return true;
        }
        $record->setFromArray($this->getValues());
        $record->save();
        return true;
      }
    }
}

Тогда в вашем контроллере вы можете сделать что-то вроде:

$form = new My_Record_Form(array(
  'record'=>$record, 
  'admin'=>My_Auth::getInstance()->hasPermission($record, 'admin')
));

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

Чтобы ответить на раздел 2: формы редактирования в моем коде возвращаются из функции модели: $record->getEditForm() Код контроллера в конечном итоге выглядит примерно так:

  protected $_domain = null;
  protected function _getDomain($allowNew = false)
  {
    if ($this->_domain)
    {
      return $this->view->domain = $this->_domain;
    } else {
      $id = $this->_request->getParam('id');
      if (($id == 'new' || $id=='') && $allowNew)
      {
        MW_Auth::getInstance()->requirePrivilege($this->_table, 'create');
        $domain = $this->_table->createRow();
      } else {
        $domain = $this->_table->find($id)->current();
        if (!$domain) throw new MW_Controller_404Exception('Domain not found');      
      }
      return $this->view->domain = $this->_domain = $domain;
    }
  }

  public function editAction()
  {
    $domain = $this->_getDomain(true);

    MW_Auth::getInstance()->requirePrivilege($domain,'edit');
    $form = $domain->getEditForm();

    if ($this->_request->isPost() && $form->process($this->_request->getPost()))
    {
      if ($form->delete && $form->delete->getValue())
      {
        return $this->_redirect($this->view->url(array(
          'controller'=>'domain', 
          'action'=>'index',
        ), null, true));
      } else {
        return $this->_redirect($this->view->url(array(
          'controller'=>'domain', 
          'action'=>'view',
          'id'=>$form->getDomain()->id,
        ), null, true));        
      }
    }    
    $this->view->form = $form;
  }

Итак - фактический идентификатор записи передается, например, в URI / domain / edit / id / 10. Если вам нужно разместить несколько таких форм на странице - вы должны обязательно установить атрибут «action» формы, чтобы он указывал на действие, специфичное для этой формы.

1 голос
/ 06 августа 2009

Я создал SimpleTable extends Zend_Db_Table и SimpleForm extends Zend_Db_Form классы. Оба из них предполагают, что ваша таблица имеет столбец идентификатора с автоинкрементом.

SimpleTable имеет функцию saveForm(SimpleForm $form), которая использует динамическое связывание для сопоставления имен элементов формы со столбцами записи. Я также включил переопределенный saveFormCustom($form) для любой специальной обработки.

У SimpleForm есть абстрактный setup(), который необходимо переопределить для настройки формы. Я использую init() для начальной настройки (например, добавление скрытого поля идентификатора).

Однако, если честно, мне действительно не нравится использовать объект Zend_Form, я чувствую, что это должно обрабатываться в представлении, а не в модели или контроллере.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...