gpt4 book ai didi

jsf-2 - 如何使用自定义渲染器渲染复合组件?

转载 作者:行者123 更新时间:2023-12-03 18:31:09 26 4
gpt4 key购买 nike

我想知道如何通过 Java 渲染复合组件,
我的意思是我有:

<myowntags:selectOneRadio>
<f:selectItem itemValue="value0" itemLabel="This is the value 0" />
<f:selectItem itemValue="value1" itemLabel="This is the value 1" />
<f:selectItem itemValue="value2" itemLabel="This is the value 2" />
</myowntags:selectOneRadio>

或者
<myowntags:selectOneRadio>
<f:selectItems value="#{controller.items}" />
</myowntags:selectOneRadio>

我想创建一个 Java 类来呈现它。

我知道如何在不使用复合 Material 的情况下呈现自定义组件,但是因为要呈现组件,我必须在 block 上指定一些值:
<renderer>
<component-family>javax.faces.SelectBoolean</component-family>
<renderer-type>javax.faces.Checkbox</renderer-type>
<renderer-class>com.myapp.CustomCheckboxRenderer</renderer-class>
</renderer>

然后我迷路了,因为我不知道这些参数的值
在复合组件的渲染标签内。

提前致谢,
天使。

最佳答案

首先,您需要有一个实现 NamingContainer 的支持组件。并返回 "javax.faces.NamingContainer"作为组件族。这是复合组件所必需的,您不能更改该部分。 UINamingContainer 实现已经这样做了,所以如果你可以从它扩展。

@FacesComponent("mySelectOneRadio")
public class MySelectOneRadio extends UINamingContainer {
// ...
}
或者如果您想从 UISelectOne 扩展,那么你必须实现 NamingContainer接口(interface)并确保返回 UINamingContainer.COMPONENT_FAMILY getFamily()覆盖。
然后,您需要在 <cc:interface componentType> 中指定它.
<cc:interface componentType="mySelectOneRadio">

请注意,在此步骤中,您已经可以通过 Java 执行渲染(编码)。只需覆盖 encodeChildren()方法。
@FacesComponent("mySelectOneRadio")
public class MySelectOneRadio extends UINamingContainer {

@Override
public void encodeChildren(FacesContext context) throws IOException {
ResponseWriter writer = context.getResponseWriter();
writer.startElement("div", this);
writer.writeText("hello world", null);
writer.endElement("div");
}

}

回到您的具体问题,因此您希望拥有一个独立的 Renderer为此上课。没关系。为此,您需要扩展 Renderer :
@FacesRenderer(componentFamily=UINamingContainer.COMPONENT_FAMILY, rendererType=MySelectOneRadioRenderer.RENDERER_TYPE)
public class MySelectOneRadioRenderer extends Renderer {

public static final String RENDERER_TYPE = "com.example.MySelectOneRadio";

@Override
public void encodeChildren(FacesContext context, UIComponent component) throws IOException {
ResponseWriter writer = context.getResponseWriter();
writer.startElement("div", component);
writer.writeText("hello world", null);
writer.endElement("div");
}

}
为了正确将此渲染器注册为默认渲染器(不要覆盖 getRendererType() 方法!否则您或其他任何人将无法通过 <renderer> 中的 faces-config.xml 更改它):
@FacesComponent("myComposite")
public class MyComposite extends UINamingContainer {

public MyComposite() {
// Set default renderer.
setRendererType(MySelectOneRadioRenderer.RENDERER_TYPE);
}

}
请注意,感谢 @FacesRenderer ,您无需为 faces-config.xml 烦恼.

无论您选择以何种方式对子组件进行编码,您都可以通过 UIComponent#getChildren() 获取组件的子组件.当你在里面时 MySelectOneRadio零件:
if (getChildCount() > 0) {
for (UICompnent child : getChildren()) {
// ...
}
}
或者当你在 MySelectOneRadioRenderer渲染器:
if (component.getChildCount() > 0) {
for (UICompnent child : component.getChildren()) {
// ...
}
}
要委托(delegate)给组件自己的默认渲染,调用 super.encodeChildren()component.encodeChildren() .要委托(delegate)给 child 自己的默认渲染,调用 child.encodeAll() .
也可以看看:
  • What is the relationship between component family, component type and renderer type?
  • 关于jsf-2 - 如何使用自定义渲染器渲染复合组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12526211/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com