考虑一个自定义 UIComponent(仅用于测试目的):
public class UITest extends UIComponentBase {
@Override
public void encodeBegin(FacesContext context) throws IOException {
System.out.println("encodeBegin");
}
@Override
public void encodeAll(FacesContext context) throws IOException {
System.out.println("encodeAll");
}
}
当我将其添加到复合组件内的页面时,encodeBegin()
方法被调用。但是,当将其添加到复合组件外部的页面时,encodeAll()
方法被调用。
将其添加到其他 UIComponent 中没有什么区别,只有复合组件包装器似乎会改变行为。
找不到信息为什么会这样?规范的链接?
在这种情况下,规范确实很混乱,指出:
“这些方法在请求处理生命周期的渲染响应阶段被调用。encodeAll() 将
导致该组件及其所有从 isRendered() 返回 true 的子组件和构面被渲染,无论
getRendersChildren() 返回值的值。编码开始(),编码儿童(),和
encodeEnd()有责任为该组件的开头创建响应数据,这
组件的子组件(仅当该组件的 rendersChildren 属性为 true 时才调用),以及
分别是这个组件。”
然而,这似乎是新旧功能的混合体,其中新功能(encodeAll)在某些方面似乎不完整:
我尝试了以下方法:
A)直接在页面中调用组件(无包装器)
扩展 UIComponentBase (或其他 UIComponent 类,如 UIInput、UIOutput 等),将其声明为标签,并在 UI 中使用它。
在这种情况下,如果存在(覆盖),则调用encodeAll方法,如果不存在,则将调用encodeBegin和encodeEnd方法!
另一件需要注意的事情是,您可以为组件创建自定义渲染器,这样您就可以将渲染逻辑与行为分开。 (通过创建另一个扩展 Renderer 的类,并使用 @FacesRenderer 对其进行注释)
这就是有趣的地方; Renderer 仅定义了encodeBegin、encodeChildren 和encodeEnd(没有提及encodeAll)。
现在逻辑似乎大致是这样的:
if (encodeAll 存在)
调用encodeAll(并且渲染器被忽略!)
else if(encodeBegin、Children 或 end 中的任何一个都存在于扩展 UIComponent 的类中)
调用在该组件中找到的方法
else if(encodeBegin, Children 或 end 存在于扩展 Renderer 的类中)
调用找到的相应方法。
所以这意味着在扩展UIComponent的类中实现encodeAll(或encodeBegin..等)会导致渲染器被忽略!
B)包装组件(抄送:实现..等)
在这种情况下,发生了与上面相同的事情,除了无论我做什么,在任何情况下都不会调用encodeAll。
结论:
看来encodeAll是实现渲染代码的某种新功能(或快捷方式),并且cc:implementation在这种情况下似乎有一个错误(它不查找encodeAll)。
我希望这至少对您有一些价值,不幸的是我无法提供更彻底的答案。 :(
似乎也没有其他人知道这件事。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)