有没有办法从Zend_Form生成视图? (只读)

时间:2010-02-19 17:52:41

标签: zend-framework zend-form zend-view

我想知道在处理CRUD时是否有一种简单的方法可以从表单对象生成视图。

我的意思是,当我们有这些选项时:VIEW |编辑|删除 我希望我的VIEW选项像EDIT选项,但没有表单元素,只需要值。

这将最大限度地减少创建这些视图所花费的时间。

有人知道这样的事吗?

5 个答案:

答案 0 :(得分:3)

在我的上一个项目中,我也遇到了这个困境。我的解决方案可能不是最优雅的,但它完成了这项工作。请注意,我使用Form viewscript装饰器代替完整的装饰器生成元素。但你可以调整这个例子来使用我认为的装饰器。我展示的是一个非常基本的例子,给你一个大致的想法。这是我做的:

class Cms_Form_Page extends Zend_Form
{
  const FOR_CREATE = 'forCreate';
  const FOR_READ   = 'forRead';
  const FOR_UPDATE = 'forUpdate';
  const FOR_DELETE = 'forDelete';

  protected $_name = 'page';

  private $_for;

  private $_viewScripts = array(
    self::FOR_CREATE => 'page-manager/partials/form-page-create.phtml',
    self::FOR_READ => 'page-manager/partials/form-page-read.phtml',
    self::FOR_UPDATE => 'page-manager/partials/form-page-update.phtml',
    self::FOR_DELETE => 'page-manager/partials/form-page-delete.phtml'
  );

  public function __construct( $for = self::FOR_CREATE, $options = null )
  {
    $this->_for = $for;

    parent::__construct( $options );
  }

  public function init()
  {
    $this->setName( $this->_name )
        ->setAttribs( array( 'accept-charset' => 'utf-8' ) )
        ->setDecorators( array(
            'PrepareElements',
            array( 'ViewScript', array( 'viewScript' => $this->_viewScripts[ $this->_for ] ) ),
            'Form'
        ) );

    $elements = array();

    swith( $this->_for )
    {
      case self::FOR_CREATE:
        $title = new Zend_Form_Element_Text( 'title' );
        $elements[] = $title;
        break
      case self::FOR_READ:
        $id = new Zend_Form_Element_Hidden( 'id' );
        $elements[] = $id;
        break;
      case self::FOR_UPDATE:
        $id = new Zend_Form_Element_Hidden( 'id' );
        $elements[] = $id;
        $title = new Zend_Form_Element_Text( 'title' );
        $elements[] = $title;
      break;
        case self::FOR_DELETE:
        $id = new Zend_Form_Element_Hidden( 'id' );
        $elements[] = $id;
        break;
      default:
        throw new Exception( 'invalid Form type' );
    }

    $submit = new Zend_Form_Element_Button( 'submit' );
    $elements[] = $submit;

    $this->addElements( $elements );
  }
}

所以,基本上,我将其中一个类常量传递给它的构造函数。基于该值,我确定表单需要哪些元素,以及如何呈现元素。

例如,对于创建,你可以有一个选择下拉表单字段,你可以在其中选择一个Locale,删除时这将是一个隐藏字段(在我的例子btw中没有显示)。

希望这能给你一些想法。

<强> PS:
在其中一个选定的视图脚本中,您可以简单地显示元素的值(以及渲染隐藏元素),例如:

<?
  $form = $this->element;
?>

... some html

// let's presume id and locale are hidden form fields for current form type 
// (Cms_Form_Page::FOR_UPDATE for instance)
<?= $form->id->renderViewHelper(); ?>
<?= $form->locale->renderViewHelper(); ?>

// and here we simply output the current locale value
// of course, you should have populated the values in the form somewhere first
<dt>Current locale:</dt>
<dd><?= $form->locale->getValue(); ?></dd>

...etc

所以,我认为你最好使用viewcript装饰器来表单,或者你可以滚动自己的表单元素装饰器来渲染隐藏字段(如果需要),并在一些html标签中简单地显示它的值。 / p>

答案 1 :(得分:1)

来自Nabble的Hector,show me this,这似乎是最好的方式:

class Default_View_Helper_FormView extends Zend_View_Helper_Abstract
{
    public function formView(Zend_Form $form)
    {
        $html = "<dl>";
        foreach ($form->getElements as $element) {
            $html .= "<dt>{$element->getLabel()}</dt>";
            $html .= "<dd>{$element->getValue()}</dd>";
        }
        $html .= "</dl>";
        return $html;
    }
}

答案 2 :(得分:0)

我不确定我是否理解,但我认为对于视图选项,您只需从模型中获取数据即可。无需通过Zend_Form访问它们。

但是如果您希望将表单设为只读,则可以将readonly(setAttrib('readonly','readonly'))属性添加到元素中。

答案 3 :(得分:0)

接受答案的唯一问题是你正在创建所有元素然后忽略它们。

使用fireeyedboy答案中的控制逻辑,您可以将所有元素切换到Zend_View_Helper_FormNote,这样做会做同样的事情。

只取决于优化是否重要。

答案 4 :(得分:0)

对接受的答案做了一些小的补充,以涵盖可能是特殊情况的常见元素:

class Default_View_Helper_FormView extends Zend_View_Helper_Abstract
{
  public function formView( Zend_Form $form )
  {
    $html = '<dl>';

    foreach ( $form->getElements() as $element ) {

      if( $element instanceof Zend_Form_Element_Submit ) {
        continue;
      }

      $html .= '<dt>' . $element->getLabel() . '</dt>';

      $value = $element->getValue();

      if( $element instanceof Zend_Form_Element_Checkbox ) {
        $value = ($value) ? 'Yes' : 'No';
      }
      else if( $element instanceof Zend_Form_Element_Select ) {
        $value = $element->getMultiOption($value);
      }

      $html .= '<dd>' . $value . '</dd>';
    }

    $html .= '</dl>';

    return $html;
  }
}