【问题标题】:Change default Zend Form Decorator on global application level?在全局应用程序级别更改默认 Zend 表单装饰器?
【发布时间】:2012-02-08 09:59:53
【问题描述】:

当然,我不想更改库/Zend。 我知道我可以创建扩展 Zend_Form 的类 My_Form 并设置自定义装饰器。比,每个表单都扩展了新类 My_Form...

有没有办法在一些插件或引导程序中设置 Zend 表单装饰器(更改默认装饰),而不更改现有表单??

或者,为所有表单覆盖默认表单装饰器的最佳方法是什么?

【问题讨论】:

    标签: zend-framework plugins zend-form bootstrapping zend-decorators


    【解决方案1】:

    我不确定我的回答是否会有所帮助,但请继续。 有一种方法可以用您自己的装饰器替换 ZF 装饰器,而无需编辑表单本身。

    解决方案 #1:

    here 描述的方法。或者简而言之:

    假设你有一个表格:

    class Form extends Zend_Form
    {
        function init ()
        {
            $this->addElement ('text', 'a', array (
                'label' => 'Name'
            ));
        }
    }
    

    然后在application.ini中有

    resources.view.helperPath.Default_View_Helper = APPLICATION_PATH "/views/helpers"
    

    添加一个新文件application/views/helpers/FormText.php

    class Default_View_Helper_FormText extends Zend_Form_Decorator_Abstract
    {
        function formText ()
        {
            return 'It is I.';
        }
    }
    

    就是这样。

    解决方案 #2:

    让我们有这个抽象类:

    abstract class Application_Style
    {
        private $_object;
    
    
    
        function __construct ($object = null)
        {
            if (isset ($object))
            {
                $this->apply ($object);
            }
        }
    
    
        function apply ($object)
        {
            $this->setObject ($object);
            if ($this->filter ())
            {
                $this->onApply ();
            }
    
            return $object;
        }
    
    
        function __call ($method, $arguments)
        {
            return call_user_func_array (array ($this->getObject (), $method), $arguments);
        }
    
    
        abstract protected function onApply ();
    
    
        protected function filter ()
        {
            return true;
        }
    
    
        function setObject ($_object)
        {
            $this->_object = $_object;
        }
    
    
        function getObject ()
        {
            return $this->_object;
        }
    }
    

    然后是后代。

    class Application_Style_AdminForm extends Application_Style
    {
        function onApply ()
        {
                $this->addElement ($submit = new Zend_Form_Element_Submit ('submit', array(
                'label' => 'Submit',
                )));
    
                $submit
                ->removeDecorator ('DtDdWrapper')
                ->addDecorator ('HtmlTag', array (
                'placement' => Zend_Form_Decorator_HtmlTag::PREPEND,
                'tag' => 'p',
                'openOnly'  => 1,
                ))
                ->addDecorator ('Custom', array ('text' => '     '))
                ;
            }
    }
    

    在 onApply() 方法中可以是任何适合你的东西。例如,添加或删除装饰器。然后你可以像这样在你的表单上调用这个样式:

    new Application_Style_AdminForm ($this);
    

    它允许您操作表单表示,但无需直接更改它。

    【讨论】:

    • 这似乎是一个不错的解决方案。因此,formText() 方法将返回一个字符串类型。该字符串替换表单上的每个文本字段,然后我应该返回类似 '' 或类似的字符串,对吗?我不能返回类型 Zend_Form_Element_Text..
    • 好的,这是一种很好的做法,但对我的问题没有帮助,感谢您的回答 +1,但我不能接受这个答案。
    【解决方案2】:

    许多人都尝试过,据我所知,没有一个在不扩展 Zend_Form 的情况下成功地做到了。请参阅 thisthis 了解次优解决方案。

    【讨论】:

      【解决方案3】:

      我有一个解决方案。您可以在 bootsrap 中定义装饰器。

      例如:-

      $textDecorator = array(
                      array('ViewHelper',
                          array('helper' => 'formText')
                      ),
                      array('Label',
                          array('class' => 'label')
                      ),
                      array('HtmlTag',
                          array('tag' => 'div', 'class' => 'formfield clearfix')
                      )
                  ); 
      
      Zend_Registry::set('text_dec', $textDecoration);
      

      现在您可以将它用于所有表单文本字段。

      例如:-

      class TestForm extends Zend_Form
      {
          function init ()
          {
              $this->addElement ('text', 'a', array (
                  'label' => 'Name',
                  'decorator' => Zend_Registry::get('text_dec')
              ));
          }
      }
      

      所以你可以使用一些全局装饰器形成这个。

      【讨论】:

      • 这样,您不必更改应用程序中每个n 表单中的1 行,而是更改m 行(对于每个元素)乘以n 表单。这比扩展Zend_Form 有什么好处?更不用说@akond 的解决方案了,这似乎是最接近 OP 想要的。
      • @bububaba 实际上,您可以使用变量来设置整个表单的装饰器,使用 setDecorators();为了真正覆盖全局的默认表单装饰器,他需要扩展 Zend_Form,因为它被设计为...... ;)
      【解决方案4】:

      这里是完整的解决方案。

      在“.ini”文件中为你的装饰器设置文件夹:

      ; folder with custom decorators will be loaded for FormElements
      form.elementPrefixPath.decorator.prefix =  "Application_Form_Decorator"
      form.elementPrefixPath.decorator.path   =  "Application/Form/Decorator/"
      form.elementPrefixPath.decorator.type   = "decorator"
      
      ; folder with custom decorators will be loaded for Forms
      form.prefixPath.decorator.prefix =  "Application_Form_Decorator"
      form.prefixPath.decorator.path   =  "Application/Form/Decorator/"
      form.prefixPath.decorator.type   = "decorator"
      

      接下来,为您的装饰器使用 同名 来覆盖默认装饰器。 例如,要替换默认的“DtDdWrapper”装饰器, 你可以使用 Application_Form_Decorator_DtDdWrapper:

      class Application_Form_Decorator_DtDdWrapper extends Zend_Form_Decorator_DtDdWrapper
      

      装饰器将由该名称的最后一部分加载。

      【讨论】:

        猜你喜欢
        • 2020-08-05
        • 2011-01-10
        • 2011-01-24
        • 1970-01-01
        • 1970-01-01
        • 2012-10-23
        • 2011-07-13
        • 1970-01-01
        • 2020-03-11
        相关资源
        最近更新 更多