我想在.xhtml文件中加载两个差异面板。
<h:inputText value="#{param['from']=='TERMINAL' ? terminalsList.globalFilter : merchantsList.globalFilter}" size="50" />
<h:commandButton value="Filter" actionListener="#{param['from']=='TERMINAL' ? terminalsList.filterTerminals : merchantsList.filterMerchants}" />
<h:commandButton value="Reset" actionListener="#{param['from']=='TERMINAL' ? terminalsList.resetTerminalsFilter : merchantsList.resetMerchantsFilter}" />
当http get request params等于'TERMINAL'时,我想加载'terminalsList'托管bean,否则'merchantsList'托管bean。
此代码无效。
答案 0 :(得分:10)
您不能在值和操作表达式中使用条件运算符?:
。值表达式将在表单提交上抛出PropertyNotWritableException
,因为EL语法不表示可写操作,而是一个只读操作。动作表达式已经在页面加载时抛出ELException: not a valid method expression
因为EL语法不表示方法表达式而是表示值表达式。
你需要以不同的方式解决它,然后以这种方式完全摆脱值和动作表达式中的条件运算符?:
。这可以通过以下几种方式实现:
使用抽象基类和标记文件。目前,您的支持bean方法名称很可能没有以两种类中完全相同的方式对齐。您只有globalFilter
属性对齐,但动作侦听器方法不对齐。我建议将其重命名为filter()
和resetFilter()
。然后,您可以从这些bean类中提取抽象基类,并在custom tag file上使用它,如下所示:
<my:filter beanName="#{param.from eq 'TERMINAL' ? 'terminalsList' : 'merchantsList'}" />
实现如下(假设这些bean是请求作用域):
<h:inputText value="#{requestScope[beanName].globalFilter}" size="50" />
<h:commandButton value="Filter" actionListener="#{requestScope[beanName].filter}" />
<h:commandButton value="Reset" actionListener="#{requestScope[beanName].resetFilter}" />
(如果您的bean位于不同的范围内,只需相应地更改#{requestScope}
,例如#{viewScope}
)
使用JSTL有条件地构建视图。这真的很笨拙(不是DRY),但对于初学者来说可能更容易,但实际上这是唯一的方法,如果由于某些不明原因而无法更改方法签名。
<c:choose>
<c:when test="#{param.from eq 'TERMINAL'}">
<h:inputText value="#{terminalsList.globalFilter}" size="50" />
<h:commandButton value="Filter" actionListener="#{terminalsList.filterTerminals}" />
<h:commandButton value="Reset" actionListener="#{terminalsList.resetTerminalsFilter}" />
</c:when>
<c:otherwise>
<h:inputText value="#{merchantsList.globalFilter}" size="50" />
<h:commandButton value="Filter" actionListener="#{merchantsList.filterMerchants}" />
<h:commandButton value="Reset" actionListener="#{merchantsList.resetMerchantsFilter}" />
</c:otherwise>
</c:choose>