Zend Framework 1.10.1 理解和使用 Zend 表单装饰器之三:装饰器分层

如果你在紧随上一节的内容,你可能会注意到一个装饰器的 render() 方法接受一个单独的参数,$content。它预期为一个字符串。render() 然后接受这个字符串,并决定是要替换它,附加在它后面,或者前置它前面。这允许你拥有一个装饰器的链条——它允许你创建只呈现元素的元数据的一个子集的装饰器,然后把这些装饰器分层来为这个元素建造全部的标记。

让我们看一下在实践中它是如何工作的。

对于大部分的表单元素类型来说,以下的装饰器被使用:

  • ViewHelper(使用一个标准表单视图帮助器来呈现表单 input)。
  • Errors(通过一个无序列表呈现验证错误)。
  • Description(呈现附加在元素上任何描述;通常用于提示 tooltips)。
  • HtmlTag(用一个 <dd> 标签包括以上的全部)
  • Label(呈现放置在以上内容之前的标签 label,用一个 <dt> 标记包围。

你将会注意到每个这些装饰器做一件事情,对存储在表单元素里的一个元数据的片断进行操作:Erros 装饰器扒下验证错误并呈现它;Label 装饰器只扒下 label 标签并呈现它。这使得独立的装饰器十分清晰,可重复,而且,更重要的,可测试。

同时,$content 参数进入什么地方扮演角色:每一个装饰器的 render() 方法被设计成接受内容,然后替换它(通常是通过包围它的方法来达到这个目的),前置在它,或者附加到它的后面。

所以,最好把装饰的过程看作从内而外创建一个洋葱。

为了简化这个过程,我们会看一下上一节提到的例子,想到:

让我们现在去掉 label 的功能,为它建立一个分离的装饰器。

现在,这可能看起来很棒,但这有一个问题:到目前为止,最后的装饰器率先冲过了终点,然后覆盖了一切。取决于你最后注册的,你最后将只得到 input,或者只是 label。

为了克服这点,简单的把传递给 $content 的内容和标记合并:

当你想从编程角度上选择原来的内容是应该前置还是附加到新的标记(markup)的时候,上面的方法就会有问题了。幸运的是,为此已经有了一个标准的机制;Zend_Form_Decorator_Abstract 有一个为与之匹配的进行替换并且定义一些常量的概念。另外,它允许在它们两个之间指定一个分割符。让我们使用这些:

注意上面我为每一个转换默认的例子,这将假设 labels 放置在内容前面,input 附加到内容后面。

现在,让我们用这些创建一个表单元素:

这个将会如何工作?当我们调用 render(),元素将迭代大量附在它身上的装饰器,对每一个装饰器都调用 render()。它会传递一个空的字符串给最开始的那个,然后创建的任何内容将会被传递给下一个,以此类推:

初始化的内容是一个空的字符串:''。 ''被传递给 SimpleInput 装饰器,然后它会产生一个表单的 input,附加到空的字符串上:<input id="bar-foo" name="bar[foo]" type="text" value="test" />。 input 然后会当作内容传递给 SimpleLabel 装饰器,产生一个 label,并且前置在原始内容的前面;默认的分割符是一个 PHP_EOL 字符,会给我们以下:<label for="bar-foo"> /n<input id="bar-foo" name="bar[foo]" type="text" value="test" />。

但是请等一下!如果出于某种原因,你想 label 出现在 input 的后面怎么办?还记得 placement 标记吗?你可把它作为一个选项传递给装饰器。最简单的方法是,在元素创建过程中,把一个选项数组连同装饰器传递给它:

注意在传递选项的时候,你必须把装饰器包裹在一个数组内;这会提示给构造函数,有可选项。装饰器的名字是那个数组的第一个元素,选项以一个数组传递给那个数组的第二个元素。

上面的结果以标记输出是 <input id="bar-foo" name="bar[foo]" type="text" value="test" />/n<label for="bar-foo">。

使用这个技巧,你可以获得以特定元素或表单的元数据为目标的装饰器,以及创建只和那个元数据相关的标记(markup)。我们的洋葱就是结果。

这种方法有利有弊。首先,不好的方面:

应用更复杂。你不得不更注意你使用的装饰器和为了按照正确的顺序来创建标记(markup)你要如何布置。 资源更集中。更多的装饰器意味着更多的对象;被在一个表单内的元素的数量相乘成倍增加,最后你可能会严重使用资源。缓存在这有用。

但是优点是令人信服的:

可重用的装饰器。通过这个技巧你真的可以创建可重用的装饰器,因为你不必担心复杂的标记(markup),只是标记一个元素或者表单元数据或是它们的一些片断。 极大的扩展性。理论上你可以通过很小数量的装饰器产生你希望的任何标记组合。

以上的例子是 Zend_Form 内置的装饰器的目标用法,但是你经常还是很难理解,装饰器如何互动来创建最后的标记(markup)。出于这个原因,1.7以后的版本,增加了一些扩展功能,来使呈现独立的装饰器变得有可能——这将和 Rails 类似的简单的呈现表单。在下一节我们会看到它。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值