早上好,JSF专家们!
让我把我想解决的问题慢慢解决。申请有多种形式。表单中的元素可以根据1)为此表单元素配置的权限集及其条件组合,以及2)从数据库加载的用户权限,标记为需要用户授权。
我正在尝试开发的解决方案如下:我实现了自定义组件,它扩展了UIComponentBase
。在表单的Facelets标记中,这个自定义组件将在授权下包装元素:
<custom:applyRights id="abc">
<p:inputText
id="inputWithRights"
value="Some placeholder..."
tabindex="0"/>
</custom:applyRights>
然后我需要修改组件树。也就是说,在构建组件树之后,我需要找到我的<custom:applyRights/>
,访问它的子树,或者保持组件不变,或者禁用它们,或者设置setRendered( false )
等等。对组件采取的具体操作也取决于组件的类型。
然后我用替换PhaseListener
@Override
public PhaseId getPhaseId() {
return PhaseId.RESTORE_VIEW;
}
在它的afterPhase(PhaseEvent phaseEvent)
中,我获得FacesContext
、UIViewRoot
的当前实例,构建new FullVisitContext(facesContext)
并尝试viewRoot.visitTree
。
但只有viewRoot被访问。
我做错了什么?也许我尝试visitTree()
太早了?那什么时候该做呢?
谢谢!
这是UIViewRoot
本身的PostAddToViewEvent
。您可以使用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>