我一直在研究如何开发JSF自定义组件以提高我对其工作原理的了解(到目前为止它非常有趣)。
我创建了自己的commandButton(从HtmlCommandButton扩展而来),它在组件类中进行所有解码和enconding时按预期工作。
当我决定为我的组件创建一个单独的面部渲染器时,它停止工作。经过一些研究后,我了解到我必须覆盖渲染器的解码方法,之前它才有效,因为这个方法已经由HtmlCommandButton实现了。
经过一些研究后,我发现了如何解码动作侦听器(thanks to BalusC),我还学会了如何解码ajax事件。但是我仍然不知道如何解码动作。
这是我现在的解码方法:
@Override
public void decode(FacesContext context, UIComponent component) {
CommandButtonUI commandButton = (CommandButtonUI) component;
//decode click ajax events
List<ClientBehavior> clientBehaviours = commandButton.getClientBehaviors().get("click");
if (clientBehaviours != null) {
for (ClientBehavior cb : clientBehaviours) {
cb.decode(context, component);
}
}
//decode action listenet
if (context.getExternalContext().getRequestParameterMap().containsKey(commandButton.getClientId(context))) {
component.queueEvent(new ActionEvent(component));
}
}
我已经尝试找到HtmlCommandButton的解码源并对其进行分析,但我找不到它,因为它显然是由插件生成的。
答案 0 :(得分:0)
我就是这样做的。但不要忘记:1)使用相应的@FacesRenderer
和componentFamily
值将rendererType
注释添加到渲染类。
2)使用类构造函数中的setRendererType
在组件类上定义组件RenderType。
public void decode(FacesContext pContext, UIComponent pComponent) {
YourComponent xButton = (DBSButton) pComponent;
String xClientId = xButton.getClientId();
if(xButton.getReadOnly()) {return;}
decodeBehaviors(pContext, xButton);
if (RenderKitUtils.isPartialOrBehaviorAction(pContext, xClientId)
|| pContext.getExternalContext().getRequestParameterMap().containsKey(xClientId)) {
xButton.queueEvent(new ActionEvent(xButton));
}
}
protected void decodeBehaviors(FacesContext pContext, UIComponent pComponent)
{
if(!(pComponent instanceof ClientBehaviorHolder)) {
return;
}
Map<String, List<ClientBehavior>> xBehaviors = ((ClientBehaviorHolder) pComponent).getClientBehaviors();
if(xBehaviors.isEmpty()) {
return;
}
Map<String, String> xParams = pContext.getExternalContext().getRequestParameterMap();
String xBehaviorEvent = xParams.get("javax.faces.behavior.event");
if(null != xBehaviorEvent) {
List<ClientBehavior> xBehaviorsForEvent = xBehaviors.get(xBehaviorEvent);
if(xBehaviorsForEvent != null && !xBehaviorsForEvent.isEmpty()) {
String xBehaviorSource = xParams.get("javax.faces.source");
String xClientId = pComponent.getClientId();
if(xBehaviorSource != null && xClientId.startsWith(xBehaviorSource)) {
for(ClientBehavior xBehavior: xBehaviorsForEvent) {
xBehavior.decode(pContext, pComponent);
}
}
}
}
}