【问题标题】:Best ways to handle Record Form in Zend FrameworkZend 框架中处理记录表单的最佳方法
【发布时间】:2009-08-03 16:06:45
【问题描述】:

一旦您对根据教程中的示例构建的基本记录表单感到满意,您就会意识到您需要设计更专业的记录表单。例如。我不想在用户和管理区域中为同一个表复制记录表单。

1) 是否有人使用某种机制(可能是继承)来减少几乎相似的管理员和用户表单的重复?这样做是不是很繁重,或者有时您最好只复制粘贴?

2) 有没有人认为构建一些基本的 Record 类是个好主意

  • 可以确定在本页的几个记录表中,当前的帖子是专门发给这个记录表的
  • 可以以某种有组织的方式区分“编辑”或“删除”按钮的点击。

3) 我目前的做法包括将所有表单配置代码(装饰器、验证、初始值)放入构造函数中,并将表单提交处理放入单独的 ProcessSubmit() 方法中,以释放控制器不必要的代码。

以上所有地址都指向了一些预期的记录表单功能,我想知道是否有任何指南、好的示例应用程序可以用于这种稍微更高级的记录处理,或者人们仍在重新设计轮子。想知道你应该走多远以及应该在哪里停下来......

【问题讨论】:

    标签: php zend-framework forms


    【解决方案1】:

    几个建议:

    首先 - 使用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;
      }
    

    所以 - 例如,记录的实际 id 在 URI /domain/edit/id/10 中传递。如果您要将多个这些表单放在一个页面上 - 您应该确保将表单的“action”属性设置为指向特定于该表单的操作。

    【讨论】:

      【解决方案2】:

      我创建了 SimpleTable extends Zend_Db_TableSimpleForm extends Zend_Db_Form 类。这两个都假设您的表有一个自动递增的 ID 列。

      SimpleTable 有一个saveForm(SimpleForm $form) 函数,它使用动态绑定将表单元素名称与记录的列进行匹配。我还包括一个可覆盖的saveFormCustom($form),用于任何特殊处理。

      SimpleForm 有一个抽象的setup(),必须覆盖它才能设置表单。我使用init() 进行初始设置(例如添加隐藏ID 字段)。

      不过,说实话,我真的不喜欢使用Zend_Form 对象,我觉得应该在 View 中处理,而不是在 Model 或 Controller 中处理。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-14
        相关资源
        最近更新 更多