在 PrimeFaces 3.4 JSF 2.0 中按 id 查找组件

findComponent by id in PrimeFaces 3.4 JSF 2.0

我想要一种在 PrimeFaces 3.4 中通过 id 查找 UIComponent 的方法。 我已经找到了执行此操作的方法,但它有一个方法 visitTree(在 PrimeFaces 5.2 中可用),它不适用于 PrimeFaces 3.4。

谁能帮我在下面的 XHTML 中找到面板对象。

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.org/ui">

<h:head></h:head>
<h:body>
    <h:form id="form">
        <p:panel id="pnl"><h:outputText value="Yahoooo...."></h:outputText></p:panel>
        <p:commandButton ajax="false" value="Toggle" actionListener="#{myBean.mytoggle}"/>
    </h:form>
</h:body>
</html>

Primefaces 5.2 工作方式

public UIComponent findComponent(final String id) {

    FacesContext context = FacesContext.getCurrentInstance(); 
    UIViewRoot root = context.getViewRoot();
    final UIComponent[] found = new UIComponent[1];

    root.visitTree(new FullVisitContext(context), new VisitCallback() {     
        @Override
        public VisitResult visit(VisitContext context, UIComponent component) {
            if(component.getId().equals(id)){
                found[0] = component;
                return VisitResult.COMPLETE;
            }
            return VisitResult.ACCEPT;              
        }
    });

    return found[0];

}

UIComponent#visitTree() 方法并不特定于任何 PrimeFaces 版本。它特定于 JSF 2.0。它应该在 JSF 2.x 之上的任何 PrimeFaces 版本 运行 上同样有效。只有当您实际上是 运行 JSF 1.x.

时才会失败

即便如此,标准的 JSF API 已经提供了 UIViewRoot#findComponent() 的工作,它只需要一个客户端 ID,而不是组件 ID。

UIViewRoot view = FacesContext.getCurrentInstance().getViewRoot();
UIComponent component = view.findComponent("form:pnl");
// ...

尽管如此,这对您的问题来说是错误的解决方案。您似乎有兴趣对其执行 setRendered(boolean) 调用。你根本不应该这样做。您不应该对模型方面的视图感兴趣。反过来做。您应该设置一个模型值,而视图又应该绑定到该模型值。

这是一个启动示例:

<h:form>
    <p:panel rendered="#{not bean.hidden}">
        <h:outputText value="Yahoooo...." />
    </p:panel>
    <p:commandButton value="Toggle" action="#{bean.toggle}" update="@form" />
</h:form>

bean 中只有这个:

private boolean hidden;

public void toggle() {
    hidden = !hidden;
}

public boolean isHidden() {
    return hidden;
}