如何解码 commandButton 动作
How to decode commandButton action
我一直在研究如何开发 JSF 自定义组件以提高我对它的工作原理的了解(到目前为止非常有趣)。
我制作了自己的 commandButton(从 HtmlCommandButton 扩展),在组件 class.
中进行所有解码和编码时,它按预期工作
当我决定为我的组件创建一个分离的面孔渲染器时,它停止工作了。经过一些研究,我了解到我必须重写我的渲染器的解码方法并且它之前工作只是因为这个方法已经由 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 的解码源并分析它,但我没有找到它,因为它显然是由插件生成的。
我就是这样做的。但不要忘记:1) 使用相应的 componentFamily
和 rendererType
值将 @FacesRenderer
注释添加到渲染 class。
2) 在 class 构造函数中使用 setRendererType
在组件 class 上定义组件 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);
}
}
}
}
}
我一直在研究如何开发 JSF 自定义组件以提高我对它的工作原理的了解(到目前为止非常有趣)。
我制作了自己的 commandButton(从 HtmlCommandButton 扩展),在组件 class.
中进行所有解码和编码时,它按预期工作当我决定为我的组件创建一个分离的面孔渲染器时,它停止工作了。经过一些研究,我了解到我必须重写我的渲染器的解码方法并且它之前工作只是因为这个方法已经由 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 的解码源并分析它,但我没有找到它,因为它显然是由插件生成的。
我就是这样做的。但不要忘记:1) 使用相应的 componentFamily
和 rendererType
值将 @FacesRenderer
注释添加到渲染 class。
2) 在 class 构造函数中使用 setRendererType
在组件 class 上定义组件 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);
}
}
}
}
}