简体   繁体   English

如果只渲染另一个组件,如何渲染组件?

[英]How to render a component only if another component is not rendered?

I have a page that the user can access via Android, iPhone, BlackBerry or via an unknown browser. 我有一个用户可以通过Android,iPhone,BlackBerry或未知浏览器访问的页面。 I have 4 rich:panel s, one for each platform and the latter is a generic one. 我有4个rich:panel ,每个平台一个,后者是通用平台。

The code: 编码:

<rich:panel id="dlAndroid" rendered="#{fn:containsIgnoreCase(request.getHeader('User-Agent'), 'Android')}">
    ...
</rich:panel>

<rich:panel id="dlIphone" rendered="#{fn:containsIgnoreCase(request.getHeader('User-Agent'), 'iPhone')}">
    ...
</rich:panel>

<rich:panel id="dlBlackberry" rendered="#{fn:containsIgnoreCase(request.getHeader('User-Agent'), 'BlackBerry')}">
    ...
</rich:panel>

<rich:panel id="dlGeneric" rendered="#{ ---> WHAT TO WRITE HERE? <--- }">

How can I render the last rich:panel only if none of the others has been rendered? 如果没有渲染其他人,我怎样才能渲染最后一个rich:panel

To the point, your question as stated in the title can concretely be answered as: 至于这一点,标题中所述的问题可以具体回答如下:

<rich:panel binding="#{panel1}" ...>
    ...
</rich:panel>
<rich:panel binding="#{panel2}" ...>
    ...
</rich:panel>
<rich:panel binding="#{panel3}" ...>
    ...
</rich:panel>
<rich:panel ... rendered="#{not panel1.rendered and not panel2.rendered and not panel3.rendered}">
    ...
</rich:panel>

However, in this particular case it's perhaps nicer to alias those long winded expressions with <c:set> : 但是,在这种特殊情况下,使用<c:set>为那些长卷曲表达式别名可能更好:

<c:set var="android" value="#{fn:containsIgnoreCase(header['User-Agent'], 'Android')}" scope="request" />
<c:set var="iPhone" value="#{fn:containsIgnoreCase(header['User-Agent'], 'iPhone')}" scope="request" />
<c:set var="blackBerry" value="#{fn:containsIgnoreCase(header['User-Agent'], 'BlackBerry')}" scope="request" />

<rich:panel ... rendered="#{android}">
    ...
</rich:panel>
<rich:panel ... rendered="#{iPhone}">
    ...
</rich:panel>
<rich:panel ... rendered="#{blackBerry}">
    ...
</rich:panel>
<rich:panel ... rendered="#{not android and not iPhone and not blackBerry}">
    ...
</rich:panel>

Note that there's a shorter way to get the request header by the implicit #{header} map. 请注意,通过隐式#{header}映射获取请求标头的方法较短。

You could write this validation on a managed bean method, so it will verify if the user-agent fits the 4th option. 您可以在托管bean方法上编写此验证,因此它将验证用户代理是否适合第4个选项。 Example: 例:

public boolean userAgentUnknownBrowser() {
// Verify if contains the user-agent String
}

And on your page, you'll just use the method: 在您的页面上,您只需使用以下方法:

<rich:panel id="dlGeneric" rendered="#{myBean.userAgentUnknownBrowser()}">

You can use 您可以使用

<c:choose>
<c:when test="#{fn:containsIgnoreCase(request.getHeader('User-Agent'), 'Android')}">
<rich:panel id="dlAndroid">
...
</rich:panel>
</c:when>
<c:when test="#{fn:containsIgnoreCase(request.getHeader('User-Agent'), 'iPhone')}">
<rich:panel id="dlIphone">
...
</rich:panel>
</c:when>
<c:otherwise>
<rich:panel id="dlGeneric">
    ...
</rich:panel>
</c:otherwise>
<c:choose>

I think you are using a logic to determine the browser type which would not change between the POSTS on the same page , so it seems safe to me to use JSTL tag here. 我认为你使用逻辑来确定在同一页面上的POSTS之间不会改变的浏览器类型,因此我在这里使用JSTL标签似乎是安全的。 JSTL tag will only execute once during CREATE VIEW for the page. JSTL标记仅在页面的CREATE VIEW期间执行一次。

However if you are testing the condition on some model variable then it is better to wrap each of the panels in ui:fragment like 但是,如果您在某个模型变量上测试条件,那么最好将每个面板包装在ui:fragment中

<ui:fragment rendered="#{fn:containsIgnoreCase(request.getHeader('User-Agent'), 'Android')}">
    <rich:panel id="dlAndroid">
    ...
    </rich:panel>
<ui:fragment>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM