如何调用有条件呈现的UICommand组件的动作方法? - 2

时间:2010-06-21 17:51:22

标签: jsf

My previous for the same problem ,现在,我处于相同的情况并寻找一些解决方案/建议。

我的限制

  1. 我的Bean必须是请求范围
  2. 我不能使用tomahawk - 我们使用基于tomcat + SOA构建的自定义应用服务器 - 等等,等等我们无法使用。
  3. 我有一组搜索结果,这些搜索结果对于每个搜索条件都是不同的(这就是为什么bean是请求范围的 - 因为用户希望在同一浏览器中使用diff选项卡来比较结果或做他想做的任何事情)。我想在prev + next等页面中显示搜索结果。

    像这样:

    <tr>
        <td colspan="14" class="WhiteRowSmallText">
            <div align="right">
                <h:commandLink rendered="#{adminBean.showPrev}" action="#{adminBean.goPrev}">
                    <h:outputText> &lt; Prev  &#160;|&#160;</h:outputText>
                </h:commandLink>
                <h:outputText> &#160;|&#160; </h:outputText>
                <h:commandLink rendered="#{adminBean.showNext}" action="#{adminBean.goNext}">
                    <h:outputText> Next &gt;</h:outputText>
                </h:commandLink> &#160;
            </div>
        </td>
    </tr>
    

    我没有为每个'下一步'点击点击数据库,而是希望将它们存储在会话中,比如

    public static Object getSessionMapValue(String key) {
        Log.debug(CLASS_NAME + "getSessionMapValue: key=" +key );
        return FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get(key);
    }
    
    public static void setSessionMapValue(String key, Object value) {
        Log.debug(CLASS_NAME + "setSessionMapValue: key=" +key );
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(key, value);
    }
    

    我的问题是:

    如果我使用此方法存储大量搜索结果,如果用户打开另一个标签,它是否仍然可用?我想是 - 不是吗?

    当结果更多时,我尝试'下一步',它甚至没有调用它的动作方法,因为创建了一个新的Bean(!)并将showNext设为'false' - 我有什么选择允许用户考虑到我上面的限制,浏览页面?

    是否可以使用隐藏的Bean变量并在单击链接时通过javascript使其成为'true'并在CustomPhaseListener中 - 并且在RESTORE VIEW PHASE中 - 根据此隐藏值将showNext设为'true'?这是值得的吗?

    欢迎所有责骂和建议。

    如果您使用inputHidden,您可能会收到ClassCast Exception,我正在尝试这样,不确定,如果这样做

    public Boolean getShowNextValue() { if(showNext != null && showNext.getValue()!= null) { log.debug("showNext.getValue() ]" +showNext.getValue()); if(((String)showNext.getValue().toString()).equals("false")) { return false; }else{ return true; } }else{ return false; } }
    

1 个答案:

答案 0 :(得分:2)

  

如果我使用这种方法存储大量搜索结果,如果用户打开另一个标签,它仍然可用吗?我想是的 - 不是吗?

我只是将bean会话作为范围。或者,您也可以将所有“to-be-session-scoped”属性从请求范围bean中分离出来,并使用这些属性创建一个新的会话范围bean。然后,您可以使用JSF托管属性工具在需要时在请求范围(操作)中注入会话作用域(用于数据)。另请参阅this example

但是,您需要记住,当webapp更忙并且同时访问时,这可能会占用更多内存。

  

当结果更多时,我尝试'下一步',它甚至没有调用它的动作方法,因为创建了一个新的Bean(!)并将showNext设为'false' - 我有什么选择允许考虑到上述限制,用户要浏览页面吗?

那是因为bean是请求范围的,并且负责rendered attribtue条件的属性在后续请求的应用请求值阶段期间没有与在后续请求的呈现响应阶段期间相同的结果。初始请求。您之前的问题(当您自己联系时)回答了解决方案。

  

可以使用隐藏的Bean变量,并在单击链接时通过javascript使其成为'true'并在CustomPhaseListener中 - 并在RESTORE VIEW PHASE中 - 将showNext设为'true'基于此隐藏价值?这是一个值得的方法吗?

如果Tomahawk真的不是一个选项,我会选择<h:inputHidden> binding

E.g。

<h:inputHidden binding="#{adminBean.showPrev}" />
<h:commandLink rendered="#{adminBean.showPrevValue}">
    ...

private HtmlInputHidden showPrev = new HtmlInputHidden(); // +getter +setter.

public void setShowPrevValue(Boolean showPrev) {
    showPrev.setValue(showPrev);
}

public Boolean getShowPrevValue() {
    return (Boolean) showPrev.getValue();
}

当您想要获取/设置bean中的“真实”布尔值时,请使用最后一个getter / setter。