考虑自定义 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");
}
}
Run Code Online (Sandbox Code Playgroud)
当我将它添加到复合组件内的页面时,该encodeBegin()方法被调用。但是,当将它添加到复合组件外部的页面时,该encodeAll()方法会被调用。
将它添加到其他 UIComponents 中没有区别,只有复合组件包装器似乎会改变行为。
找不到信息为什么会这样?规范的链接?
小智 5
在这种情况下,规范真的很混乱,指出:“这些方法在请求处理生命周期的渲染响应阶段被调用。encodeAll() 将导致这个组件及其所有从 isRendered() 返回 true 的子组件和构面渲染,不管 getRendersChildren() 返回值的值。encodeBegin()、encodeChildren() 和 encodeEnd() 有责任为这个组件的开始创建响应数据,这个组件的子组件(仅当 rendersChildren此组件的属性为真),以及此组件的结尾。”
但是,这似乎是新旧功能的混合体,其中新功能 (encodeAll) 在某些方面似乎不完整:
我尝试了以下方法:
A) 直接在页面中调用组件(无包装)
扩展 UIComponentBase(或其他 UIComponent 类,如 UIInput、UIOutput.. 等),将其声明为标签,并在 UI 中使用它。在这种情况下,如果存在(覆盖)则调用 encodeAll 方法,否则将调用 encodeBegin 和 encodeEnd 方法!!
另外要注意的是,您可以为组件创建自定义渲染器,以便将渲染逻辑与行为分开。(通过创建另一个扩展 Renderer 的类,并使用 @FacesRenderer 对其进行注释)这就是有趣的地方;Renderer 只定义了 encodeBegin、encodeChildren 和 encodeEnd(没有提到 encodeAll)。现在的逻辑似乎大致是这样的:如果(encodeAll 存在)encodeAll 被调用(并且渲染器被忽略!) else if(任何 encodeBegin、Children 或 end 存在于扩展 UIComponent 的类中)调用该方法在该组件中找到 else if(encodeBegin, children 或 end 存在于扩展 Renderer 的类中) 调用找到的相应方法。
所以这意味着在扩展 UIComponent 的类中实现 encodeAll(或 encodeBegin.. 等)会导致渲染器被忽略!
B) 包装组件 (cc:implementation.. 等)
在这种情况下,发生了与上面相同的事情,除了在任何情况下都没有调用 encodeAll,无论我做什么。
结论:encodeAll 似乎是实现渲染代码的某种新功能(或快捷方式),而且 cc:implementation 在这种情况下似乎有一个错误(它不寻找 encodeAll)。
我希望这至少对您有价值,不幸的是我无法提供更彻底的答案。:( 似乎也没有其他人知道这一点。
| 归档时间: |
|
| 查看次数: |
4145 次 |
| 最近记录: |