使用阶段侦听器以编程方式将参数添加到Html CommandLink

时间:2015-01-16 16:57:41

标签: jsf parameters commandlink phaselistener

我需要通过阶段侦听器以非语的方式将组件( UIParameter )添加到 HtmlCommandLink 组件。 我想要实现的是每个元素<h:link outcome="out">都呈现为<a href="out_url_parsed + ?param=paramvalue">。其中&#34; param&#34;是我的组成部分。

我已尝试使用此

private void addElement(final PhaseEvent event, final Class clazz, final UIComponent component) {
    final FacesContext fcontext = event.getFacesContext();
    UIViewRoot root = fcontext.getViewRoot();
    if (root == null) {
        return;
    }

    root.visitTree(new FullVisitContext(fcontext), new VisitCallback() {

        @Override
        public VisitResult visit(VisitContext context, UIComponent target) {
            if (clazz.isInstance(target)) {
                LOGGER.info("Element Found");
                UIParameter parameter = new UIParameter();
                parameter.setValue("willberonadom");
                parameter.setId("sessiontoken");
                target.getChildren().add(parameter);

            }
            return VisitResult.ACCEPT;
        }
    });
}

但它没有用。该元素实际上在树上找到,但UIParameter不会渲染。

我发现UIViewRoot在RENDER_RESPONSE阶段之后只有子元素。所以我认为这就是为什么我添加的元素不会在流程结束时呈现的原因。

我确定我可以添加此参数来编辑视图,但我不想这样做,因为它必须出现在应用程序中的所有h:链接上,并且必须出现在任何其他添加的新视图上太。因此,我认为这是避免丢失标签的更好方法

在类似的情况下,我设法使用此代码向视图中的每个表单添加输入隐藏元素...

HtmlInputHidden hiddenToken = new HtmlInputHidden();
hiddenToken.setId("sessiontoken");
hiddenToken.setValue("willberandom");
hiddenToken.setRendered(true);
root.addComponentResource(event.getFacesContext(), hiddenToken,"form");

但它不适用于锚标记

1 个答案:

答案 0 :(得分:2)

有几个错误:

  1. 您想要将参数添加到代表HtmlCommandLink<h:commandLink>组件中,但您要提供<h:link>的示例,该示例由{HtmlOutcomeTargetLink表示3}}。你究竟想要什么?

  2. beforePhase() RENDER_RESPONSE PhaseListener上的PhaseListener在GET请求上可能为时已晚,这只会在呈现期间第一次构建视图响应。在UIViewRoot运行的那一刻,id根本就没有孩子。您可以更好地挂钩视图构建时间。为此,SystemEventListener PostAddToViewEvent是最合适的。

  3. 您已将参数名称设为name而非UIParameter#setName()。使用UIParameter#setId()代替<h:link>

  4. 如果您确实想将它们添加到SystemEventListener组件,那么这是一个启动示例,您可以使用public class YourSystemEventListener implements SystemEventListener { @Override public boolean isListenerForSource(Object source) { return source instanceof HtmlOutcomeTargetLink; } @Override public void processEvent(SystemEvent event) throws AbortProcessingException { UIParameter parameter = new UIParameter(); parameter.setName("sessiontoken"); parameter.setValue("willberonadom"); ((UIComponent) event.getSource()).getChildren().add(parameter); } } 来实现这一目标。

    <h:commandLink>

    (如果您确实想要在isListenerForSource()上应用它们,只需使用|| source instanceof HtmlCommandLink

    扩展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> </system-event-listener> </application>

    中按如下方式注册
    {{1}}