在完全构建的组件树上最早访问 visitTree() 的时刻?

The earliest moment to visitTree() on fully built Component Tree?

早上好,JSF 专家们!

让我弄清楚我要解决的问题。该应用程序有多种形式。表单中的元素可以标记为需要用户根据 1) 为该表单元素配置的权限及其条件组合和 2) 从 db 加载的用户权限。

我尝试开发的解决方案如下:我实现自定义组件,它扩展了 UIComponentBase。在表单的 Facelets 标记中,此自定义组件将根据授权包装元素:

<custom:applyRights id="abc">
    <p:inputText
        id="inputWithRights"
        value="Some placeholder..."
        tabindex="0"/>
</custom:applyRights>

然后我需要修改组件树。 IE。在构建组件树之后,我需要找到我的 <custom:applyRights/>,访问它的子树,然后保持组件不变,或者禁用它们,或者设置 setRendered( false ) 等。对组件采取的具体操作也取决于关于组件的类型。

然后我用 PhaseListener 实现:

@Override
public PhaseId getPhaseId() {
    return PhaseId.RESTORE_VIEW;
}

在其 afterPhase(PhaseEvent phaseEvent) 中,我获取 FacesContextUIViewRoot 的当前实例,构建 new FullVisitContext(facesContext) 并尝试 viewRoot.visitTree

但是只有 viewRoot 被访问。

我做错了什么?也许我想 visitTree() 太早了?那应该什么时候做呢?

谢谢!

这就是如下所示的 PostAddToViewEvent of the UIViewRoot itself. You can hook into it using a SystemEventListener 实现:

public class YourSystemEventListener implements SystemEventListener {

    @Override
    public boolean isListenerForSource(Object source) {
        return (source instanceof UIViewRoot);
    }

    @Override
    public void processEvent(SystemEvent event) throws AbortProcessingException {
        UIViewRoot view = (UIViewRoot) event.getSource();
        // ...
    }

}

faces-config.xml<application> 中注册,如下所示:

<system-event-listener>
    <system-event-listener-class>com.example.YourSystemEventListener</system-event-listener-class>
    <system-event-class>javax.faces.event.PostAddToViewEvent</system-event-class>
    <source-class>javax.faces.component.UIViewRoot</source-class>
</system-event-listener>