Jac*_*cob 6 jsf encoding hyperlink custom-renderer custom-component
我有 2 个元素,香蕉和一个 outputText,其中香蕉是一个自定义 JSF 组件,在香蕉渲染器中,我想生成包含指定元素的 HTML。
html:
<h:outputText id="theApple" value="This is an Apple" />
.
.
.
<my:banana for="theApple" link="http://www.banana.com" />
Run Code Online (Sandbox Code Playgroud)
香蕉渲染器(将目标元素包含在锚链接中):
@Override
public void encodeBegin(FacesContext context, UIComponent component) throws IOException {
ResponseWriter responseWriter = context.getResponseWriter();
Banana banana = Banana.class.cast(component);
responseWriter.startElement("a", null);
responseWriter.writeAttribute("id", banana.getClientId(context), null);
responseWriter.writeAttribute("href", banana.getLink(), null);
}
@Override
public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
ResponseWriter responseWriter = context.getResponseWriter();
Banana banana = Banana.class.cast(component);
responseWriter.endElement("a");
}
Run Code Online (Sandbox Code Playgroud)
我想要达到的目标:
<a href="http://www.banana.com">This is an Apple</a>
.
.
.
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我不想在香蕉组件上编码,而是在它使用“for”属性定位的元素上进行编码。我看到的最接近的例子是 PrimeFaces 工具提示,但我不太明白它是如何利用“for”属性的。 http://www.primefaces.org/showcase/ui/overlay/tooltip/tooltipOptions.xhtml#
如果有人能指出我正确的方向,我将不胜感激。谢谢你。
您可以在PreRenderViewEvent. 在那一刻,保证所有组件都存在于树中,并且通过在树中添加/移动/删除组件来保证操作组件树是安全的。您可以通过 找到树中的其他组件UIComponent#findComponent()。您可以使用UIComponent#getParent()和遍历组件树UIComponent#getChildren()。在getChildren()返回这是保证安全的过程中操纵一个可变的列表PreRenderViewEvent。
鉴于您想用超链接包装给定的组件,并且已经存在一个 JSF 超链接组件<h:outputLink>,因此更容易扩展和重用它以保持代码简单和干燥。这是一个基本的开球示例:
@FacesComponent(createTag=true)
public class Banana extends HtmlOutputLink implements SystemEventListener {
public Banana() {
getFacesContext().getViewRoot().subscribeToViewEvent(PreRenderViewEvent.class, this);
}
@Override
public boolean isListenerForSource(Object source) {
return source instanceof UIViewRoot;
}
@Override
public void processEvent(SystemEvent event) throws AbortProcessingException {
String forClientId = (String) getAttributes().get("for");
if (forClientId != null) {
UIComponent forComponent = findComponent(forClientId);
List<UIComponent> forComponentSiblings = forComponent.getParent().getChildren();
int originalPosition = forComponentSiblings.indexOf(forComponent);
forComponentSiblings.add(originalPosition, this);
getChildren().add(forComponent);
}
}
}
Run Code Online (Sandbox Code Playgroud)
<!DOCTYPE html>
<html lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:my="http://xmlns.jcp.org/jsf/component"
>
<h:head>
<title>SO question 38197494</title>
</h:head>
<h:body>
<h:outputText id="theApple" value="This is an Apple" />
<my:banana for="theApple" value="http://www.banana.com" />
</h:body>
</html>
Run Code Online (Sandbox Code Playgroud)
请注意,children.remove()当您已经执行了children.add(). 它会自动照顾孩子的父母。
| 归档时间: |
|
| 查看次数: |
1433 次 |
| 最近记录: |