Zend_Framework 装饰器将 Label 和 ViewHelper 包装在 div 内

2023-11-26

我对 zend 装饰混乱很陌生,但我有两个重要的问题我无法解决。问题一后面是一些例子

$decorate = array(
    array('ViewHelper'),
    array('Description'),
    array('Errors', array('class'=>'error')),
    array('Label', array('tag'=>'div', 'separator'=>' ')),
    array('HtmlTag', array('tag' => 'li', 'class'=>'element')),
);

...

$name = new Zend_Form_Element_Text('title');
$name->setLabel('Title')
    ->setDescription("No --- way");

$name->setDecorator($decorate);

哪个输出

<li class="element">
    <label for="title" class="required">Title</label> 
    <input type="text" name="title" id="title" value="">
    <p class="hint">No --- way</p>
    <ul class="error">
        <li>Value is required and can't be empty</li>
    </ul>
</li>

问题#1

我该如何包裹labelinput围绕 div 标签?所以输出如下:

<li class="element">
    <div>
        <label for="title" class="required">Title</label> 
        <input type="text" name="title" id="title" value="">
    </div>
    <p class="hint">No --- way</p>
    <ul class="error">
        <li>Value is required and can't be empty</li>
    </ul>
</li>

问题#2

的顺序是怎么回事elements in the $decorate array? 他们毫无意义!


The 装饰器模式是一种设计模式,用于向现有类添加功能而不更改这些现有类。相反,装饰器类将自身包装在另一个类周围,并且通常公开与被装饰类相同的接口。

基本示例:

interface Renderable
{
    public function render();
}

class HelloWorld
    implements Renderable
{
    public function render()
    {
        return 'Hello world!';
    }
}

class BoldDecorator
    implements Renderable
{
    protected $_decoratee;

    public function __construct( Renderable $decoratee )
    {
        $this->_decoratee = $decoratee;
    }

    public function render()
    {
        return '<b>' . $this->_decoratee->render() . '</b>';
    }
}

// wrapping (decorating) HelloWorld in a BoldDecorator
$decorator = new BoldDecorator( new HelloWorld() );
echo $decorator->render();

// will output
<b>Hello world!</b>

现在,您可能会想,因为Zend_Form_Decorator_*类是装饰器,并且有一个render方法,这自动意味着修饰类的输出'render方法将始终由装饰器用附加内容包装。但是,通过检查上面的基本示例,我们可以很容易地看出,当然情况不一定必须如此,如这个附加(尽管相当无用)示例所示:

class DivDecorator
    implements Renderable
{
    const PREPEND = 'prepend';
    const APPEND  = 'append';
    const WRAP    = 'wrap';

    protected $_placement;

    protected $_decoratee;

    public function __construct( Renderable $decoratee, $placement = self::WRAP )
    {
        $this->_decoratee = $decoratee;
        $this->_placement = $placement;
    }

    public function render()
    {
        $content = $this->_decoratee->render();
        switch( $this->_placement )
        {
            case self::PREPEND:
                $content = '<div></div>' . $content;
                break;
            case self::APPEND:
                $content = $content . '<div></div>';
                break;
            case self::WRAP:
            default:
                $content = '<div>' . $content . '</div>';
        }

        return $content;
    }
}

// wrapping (decorating) HelloWorld in a BoldDecorator and a DivDecorator (with DivDecorator::APPEND)
$decorator = new DivDecorator( new BoldDecorator( new HelloWorld() ), DivDecorator::APPEND );
echo $decorator->render();

// will output
<b>Hello world!</b><div></div>

事实上,这基本上就是很多Zend_Form_Decorator_*如果装饰器具有这种放置功能是有意义的,那么装饰器就可以工作。

对于有意义的装饰器,您可以使用setOption( 'placement', 'append' )例如,或者通过传递选项'placement' => 'append'例如,选项数组。

For Zend_Form_Decorator_PrepareElements例如,这个放置选项是无用的,因此被忽略,因为它准备了供表单使用的表单元素ViewScript装饰器,使其成为不接触被装饰元素的渲染内容的装饰器之一。

根据各个装饰器的默认功能,装饰类的内容可以被包装、附加、前置或丢弃or在将内容传递给下一个装饰器之前,会对装饰类执行完全不同的操作,而不直接向内容添加某些内容。考虑这个简单的例子:

class ErrorClassDecorator
    implements Renderable
{
    protected $_decoratee;

    public function __construct( Renderable $decoratee )
    {
        $this->_decoratee = $decoratee;
    }

    public function render()
    {
        // imagine the following two fictional methods
        if( $this->_decoratee->hasErrors() )
        {
            $this->_decoratee->setAttribute( 'class', 'errors' );
        }

        // we didn't touch the rendered content, we just set the css class to 'errors' above
        return $this->_decoratee->render();
    }
}

// wrapping (decorating) HelloWorld in a BoldDecorator and an ErrorClassDecorator
$decorator = new ErrorClassDecorator( new BoldDecorator( new HelloWorld() ) );
echo $decorator->render();

// might output something like
<b class="errors">Hello world!</b>

现在,当你为 a 设置装饰器时Zend_Form_Element_*元素,它们将被包装,并随后按照它们添加的顺序执行。所以,按照你的例子:

$decorate = array(
    array('ViewHelper'),
    array('Description'),
    array('Errors', array('class'=>'error')),
    array('Label', array('tag'=>'div', 'separator'=>' ')),
    array('HtmlTag', array('tag' => 'li', 'class'=>'element')),
);

...基本上发生的事情如下(为简洁起见,实际的类名被截断):

$decorator = new HtmlTag( new Label( new Errors( new Description( new ViewHelper() ) ) ) );
echo $decorator->render();

因此,在检查示例输出时,我们应该能够提取各个装饰器的默认放置行为:

// ViewHelper->render()
<input type="text" name="title" id="title" value="">

// Description->render()
<input type="text" name="title" id="title" value="">
<p class="hint">No --- way</p> // placement: append

// Errors->render()
<input type="text" name="title" id="title" value="">
<p class="hint">No --- way</p>
<ul class="error"> // placement: append
    <li>Value is required and cant be empty</li>
</ul>

// Label->render()
<label for="title" class="required">Title</label> // placement: prepend
<input type="text" name="title" id="title" value="">
<p class="hint">No --- way</p>
<ul class="error">
    <li>Value is required and cant be empty</li>
</ul>

// HtmlTag->render()
<li class="element"> // placement: wrap
    <label for="title" class="required">Title</label>
    <input type="text" name="title" id="title" value="">
    <p class="hint">No --- way</p>
    <ul class="error">
        <li>Value is required and cant be empty</li>
    </ul>
</li>

你知道什么?这实际上is所有相应装饰器的默认位置。

但现在最困难的部分来了,我们需要做什么才能得到您想要的结果?为了包裹label and input我们不能简单地这样做:

$decorate = array(
    array('ViewHelper'),
    array('Description'),
    array('Errors', array('class'=>'error')),
    array('Label', array('tag'=>'div', 'separator'=>' ')),
    array('HtmlTag', array('tag' => 'div')), // default placement: wrap
    array('HtmlTag', array('tag' => 'li', 'class'=>'element')),
);

...因为这将包装所有前面的内容(ViewHelper, Description, Errors and Label) 带有一个 div,对吗?甚至不...添加的装饰器将被下一个装饰器替换,因为如果装饰器属于同一类,则装饰器将被后面的装饰器替换。相反,你必须给它一个唯一的密钥:

$decorate = array(
    array('ViewHelper'),
    array('Description'),
    array('Errors', array('class'=>'error')),
    array('Label', array('tag'=>'div', 'separator'=>' ')),
    array(array('divWrapper' => 'HtmlTag'), array('tag' => 'div')), // we'll call it divWrapper
    array('HtmlTag', array('tag' => 'li', 'class'=>'element')),
);

现在,我们仍然面临这样的问题divWrapper将包装所有前面的内容(ViewHelper, Description, Errors and Label)。所以我们需要在这里发挥创意。有很多方法可以实现我们想要的。我举一个例子,这可能是最简单的:

$decorate = array(
    array('ViewHelper'),
    array('Label', array('tag'=>'div', 'separator'=>' ')), // default placement: prepend
    array(array('divWrapper' => 'HtmlTag'), array('tag' => 'div')), // default placement: wrap
    array('Description'), // default placement: append
    array('Errors', array('class'=>'error')), // default placement: append
    array('HtmlTag', array('tag' => 'li', 'class'=>'element')), // default placement: wrap
);

有关更多说明Zend_Form我建议阅读 Zend Framework 的首席开发人员 Matthew Weier O'Phinney 的文章关于 Zend 表单装饰器的文章

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Zend_Framework 装饰器将 Label 和 ViewHelper 包装在 div 内 的相关文章

  • zend 框架 where 查询中的语句

    我如何使用 php 和 zend 框架在 mysql 查询中使用 And or 现在我正在使用这个 db Zend Db Table getDefaultAdapter select new Zend Db Select db select
  • 在 Google Analytics 中准确报告通过 PayPal 进行的付款的推荐人

    在我们的 Google Analytics 电子商务中 PayPal 被视为推荐人 我发现许多文章概述了 utmnooveride 的使用 以确保 PayPal 交易传递数据 以便原始推荐人获得信用 我们使用 PayPal 处理我们的信用卡
  • (Zend Framework > Zend_Config) 如何避免使用 .ini 或 .xml 配置?

    我认为对于高流量项目来说使用 ini 或 xml 文件不是一个好主意 因为每个页面加载都会导致解析 config ini 或 xml 文件 有什么方法可以用常规 php 数组替换使用 ini xml 作为配置吗 现在 php ini 看起来
  • 无法在 Zend Framework 中回滚事务

    我在 Zend Framework 中使用以下代码进行事务 但回滚功能不起作用 数据通过 insertSome data 插入数据库 怎么了 db gt beginTransaction try model gt insertSome da
  • 如何在 Zend MVC 中实现 SSL

    我之前已经通过使用特定的安全文件夹 例如服务器上的 https 文件夹与 http 文件夹 实现了安全页面 我已经开始使用 Zend Framework 并希望应用程序的某些部分 例如登录 使用 https 我在谷歌上搜索过 甚至在这里搜索
  • 如何在没有 session_destroy 的情况下销毁 Zend_Session_Namespace

    我使用以下方法在临时会话中存储一些值 job new Zend Session Namespace application 我如何只销毁会话应用无需清除所有会话 要从会话中删除值 请对对象属性使用 PHP 的 unset 函数 假设 job
  • 用于 Eclipse PDT 的 Zend 框架插件

    我安装了 eclipse PDT IDE 版本 1 2 0 我将它与 Dojo 一起使用来开发非常有趣的 Ajax 应用程序 现在我想在我的 eclipse IDE 中启用 Zend 框架 我怎样才能做到这一点 经过一番谷歌搜索后 我尝试了
  • 如何在 Zend 中使用 cookie?

    如何使用 Zend Http Cookie 来设置和读取 cookie 我尝试像这样设置cookie cookie new Zend Http Cookie TestCookie TestValue localhost com 但没有生成c
  • Zend 1.11 和 Doctrine 2 自动从现有数据库生成所需的一切

    我是 ORM 新手 我真的很想学习它 我按照本教程成功地使用 Zend 1 11 x 安装了 Doctrine 2 1 的所有类和配置 http www zendcasts com unit testing doctrine 2 entit
  • 以编程方式添加数字签名外观?

    我正在以编程方式对我的 PDF 文件进行签名 并且我想将签名外观添加到 PDF 我需要哪些对象才能实现此目的 我知道我必须Annotations BBox and XObject但我真的不知道按什么顺序以及是否需要其他东西 调试此类内容以找
  • Zend Framework - Flashmessenger - 只有一个字符

    我在使用 FlashMessenger 时遇到了一些问题 当我想检索布局中的消息时 它会写入消息的第一个字母 示例 test 显示 t 我尝试了发布的解决方案这个问题 https stackoverflow com questions 10
  • ZF2 路由与 ZF1 相同

    如何使路由自动适用于 ZF1 结构中的所有内容 模块 控制器 操作 par1Name par1Val par2Name par2Val 我阅读了有关路由的信息 但在我看来 我必须手动添加所有操作 并且我发现可选参数存在问题 您可以至少在每个
  • 使用 Zend 实现 WURFL 时出现错误

    我环顾四周 似乎找不到与我有同样问题的人 希望我没有错过这里的叮当声 我想要获取每个用户的设备浏览器信息 我目前计划在引导程序中执行此操作 遵循我在 PHP 会议上看到的内容 为此我遇到了 http framework zend com m
  • PHPUnit 和 Zend Framework assertRedirectTo() 问题

    我在创建的测试中遇到了 assertRedirectTo 问题 下面是我使用的代码 public function testLoggedInIndexAction this gt dispatch this gt assertControl
  • 优化我的表现

    我正在开发一个使用 Zend Framework 1 11 Doctrine 2 一些 Symfony 2 组件以及其他工具和库的项目 我正在尝试使用 Xdebug 和 Webgrind 优化性能 我已经发现了一些瓶颈 例如解析 Ini 配
  • Zend Framework 生成唯一的字符串

    我想生成一个唯一的 4 6 个字符长的字母数字字符串 以便与每个记录 用户 一起保存在数据库中 db 字段具有唯一索引 因此尝试保存预先存在的字符串会生成错误 现在我正在生成一个随机字符串并使用 try catch 因此在添加新记录时如果抛
  • Sublime text 2 - 在 Zend Framework 中按类名查找文件

    当您按下Ctrl p当您可以轻松找到该文件时 Sublime 将打开弹出窗口 当您按下时 Sublime 自动检测两种情况下的文件位置 或文件路径部分之间的空格 在 Zend Framework 中 所有类的名称都在以下模板中 Namesp
  • Zend Mysql 获取 ENUM 值

    I use Zend Framework在我的应用程序中 我想知道如何从 ENUM 字段中获取值MySQL table 例如 我有permissions field ENUM 删除管理员 edit admin 如何以最佳方式获取数组 删除管
  • Zend Framework 调用另一个控制器操作

    您好 我在这里遇到调用另一个控制器操作来发送邮件的问题 这是我的代码 user php public function followAction follow id this gt getParam id response a href c
  • 将 Zend Framework 最小化为 Zend_Mail? [复制]

    这个问题在这里已经有答案了 可能的重复 在没有实际框架的情况下使用 Zend Framework 组件 https stackoverflow com questions 1402989 use zend framework compone

随机推荐