我们有一个自定义组件库,它基本上只是用 Bootstrap 类装饰库存的 Faces 组件(基本上是现在已死的 BootFaces 项目的继承者)。
我们想要做的是有一个带有表单的“整个厨房水槽”的主题......所以当你添加一个输入组件时,它会自动在对象周围包含一些填充,标签,实际输入,然后是输入消息。
解决这个问题的一种方法是实现一堆复合组件:https://stackoverflow.com/tags/composite-component/info但是在某些情况下我们需要非常严格地控制渲染的内容,因为bootstrap 有一些有趣的怪癖。
所以在输入组件的情况下,我们希望开发人员做这样的事情:
<mf:inputText .../>
但这真的给了他们:
- inputTextParent
- padding component
- label component
- actual input field component
- message component
在inputTextParent中,修改组件树和添加子组件有没有合适的方法? 更重要的是如果有人这样做:
<mf:inputText ...>
<h:somethingElse ../>
</mf:inputText>
有没有办法将
<h:somethingElse ../>
委托给子组件?
- inputTextParent
- padding component
- label component
- actual input field component
- h:somethingElse
- message component
现在,我们正在组件的构造函数中粗略地执行此操作......这不会正确地将
h:somethingElse
委托为actual input field component
的子级。而且我确定这不是操纵组件树的合法时间!
public MFInputTextComponentParent() {
setRendererType(getComponentName());
final FacesContext context = FacesContext.getCurrentInstance();
final Application application = context.getApplication();
final MFPadComponent pad = (MFPadComponent) application.createComponent(MFPadComponent.COMPONENT);
pad.setPadType("y");
pad.setPad(1);
super.getChildren().add(pad);
final MFInternalLabelComponent label = (MFInternalLabelComponent) application
.createComponent(MFInternalLabelComponent.COMPONENT);
pad.getChildren().add(label);
final MFInternalInputTextComponentParent inputText = createInternalInputText(application);
pad.getChildren().add(inputText);
final MFInternalMessageComponent message = (MFInternalMessageComponent) application
.createComponent(MFInternalMessageComponent.COMPONENT);
pad.getChildren().add(message);
}
这里的技巧是使用
PostAddToViewEvent
进一步填充带有附加子组件的 JSF 视图根树。这里的关键是给你添加的每个组件一个唯一的 ID。另见第 2.12 节动态组件:
https://github.com/e-Contract/enterprise-jsf/releases/download/enterprise-jsf-1.3.0/enterprise-jsf.pdf