JSF ui:composition 和复合组件的问题

Posted

技术标签:

【中文标题】JSF ui:composition 和复合组件的问题【英文标题】:Issue with JSF ui:composition and composite component 【发布时间】:2012-09-03 09:56:22 【问题描述】:

我正在尝试找出这是 JSF/EL 问题还是这里有什么问题。

基本上,我想将项目对象作为 ui:param 传递给 ui:composition 并在内部有一个按钮(即引导按钮,因此它们实际上是 html 链接,因此使用 commandLink)并让它执行一个动作使用项目参数。这是传递一些参数的 ui:composition item.xhtml。

<ui:include src="comp/item.xhtml">
    <ui:param name="item" value="#itemVM.item"/>
    <ui:param name="desc" value="#true"/>
</ui:include>

现在我希望这个按钮成为一个复合组件“bt:button”,但是它似乎在解析“item”参数时遇到了问题。为了确认这一点,我从组件中取出命令链接并将其放在页面上,果然它确实有效。此外,如果我将 bt:button 移到 ui:composition 之外,它也可以在那里工作。最后,如果我使用像“test”这样的单引号将项目更改为字符串,它也可以正常工作(出于测试目的,我的操作方法需要一个对象)。基于这 3 种情况,看起来复合组件在解析传递给组合的项目参数时遇到了问题。

这是 item.xhtml 中第一个测试的示例(即复合组件与常规 JSF 命令链接):

<!- This composite component doesn't Work -->
<bt:button id="cmpBtn" active="#user.compares[item.id]"
           disabled="#user.compares[item.id] != null and itemsCtr.numOfCompares >= 100"
           styleClass="btn-item-compare btn-small"
           style="margin-bottom:5px"
           action="#itemsCtr.compare(item)">
    <i class="#user.compares[item.id] != null ? 'icon-minus' : 'icon-plus'"/>
    <h:outputText value="#user.compares[item.id] != null ? 'Comparing' : 'Compare'"/>
    <f:ajax render="@this"/>
</bt:button>

<!-- This regular jsf component works -->
<h:commandLink action="#itemsCtr.compare(item)" value="Test">
    <f:ajax render="@this"/>
</h:commandLink>

这是我对 bt:button 的复合组件定义:

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:cc="http://java.sun.com/jsf/composite"
      xmlns:f="http://java.sun.com/jsf/core">

<cc:interface componentType="LinkComponent">
    <cc:attribute name="action" targets="button"/>
    <cc:attribute name="value" type="java.lang.String"/>
    <cc:attribute name="active" type="java.lang.Boolean"/>
    <cc:attribute name="title" type="java.lang.String"/>
    <cc:attribute name="styleClass" type="java.lang.String"/>
    <cc:attribute name="disabled" type="java.lang.Boolean"/>
    <cc:attribute name="style" type="java.lang.String"/>
</cc:interface>

<cc:implementation>
    <h:commandLink id="button" binding="#cc.link"
                   styleClass="btn #cc.attrs.active ? 'active' : '' #cc.attrs.disabled ? 'disabled' : '' #cc.attrs.styleClass"
                   title="#cc.attrs.title" style="#cc.attrs.style" disabled="#cc.attrs.disabled" value="#cc.attrs.value">
        <cc:insertChildren/>
    </h:commandLink>
</cc:implementation>
</html>

我的问题是这是一个 JSF 问题还是这里有什么问题?也许在复合组件定义中?

【问题讨论】:

您当前使用的是哪个 JSF 版本和实现? 我正在使用 Mojarra 2.1.11 #item 来自哪里?来自重复组件?如果有,是哪一个? #item 来自#itemVM.item。 ItemVM 只是一个 ViewScoped 托管 bean,在这种情况下没有使用 ui:repeat。我获取该属性并使用ui:param name="item" value="#itemVM.item" 将其传递给item.xhtml 组合。我创建了一个 item.xhtml 组合,因为我想在几页中重用该 jsf/html 代码,因此通过将 item 作为 ui:param 传递它允许我这样做 - 直到我遇到这个问题。 /跨度> 这似乎是 JSF 错误 JAVASERVERFACES_SPEC_PUBLIC-1223。 SO 答案JSF Combine ui:param with composite component 描述了一种解决方法。 【参考方案1】:

我和你有同样的需求,做了一个复合组件,和你一样在其中插入了带有视图参数的子元素作为属性,并且值始终为null,所以我认为这是一个JSF问题。

【讨论】:

是的,鉴于我的其他 2 种方法与 ui 参数一起工作得很好,我怀疑这是与复合组件和 ui 参数评估有关的 JSF 问题。很高兴听到我不是唯一的人,但希望它能奏效。【参考方案2】:

尝试替换

disabled="#user.compares[item.id] != null and itemsCtr.numOfCompares >= 100"

disabled="#user.compares[item.id] != null and itemsCtr.numOfCompares ge 100"

【讨论】:

您介意编辑您的答案以使其更易于理解吗? 不幸的是,这是一个旧项目,我不再有上述测试可用。但是,我看不出用 'ge' 替换 '>=' 在这里会有什么不同。问题是 'item' 参数没有被解析,而逻辑评估本身在使用 '>=' 时运行良好。【参考方案3】:

我不确定,但我想你应该尝试更换

#user.compares[item.id]

#user.compares[item]['id']

【讨论】:

以上是关于JSF ui:composition 和复合组件的问题的主要内容,如果未能解决你的问题,请参考以下文章

如何在 JSF 2 中以编程方式或动态创建复合组件

将 JavaScript 集成到 JSF 复合组件中,干净的方式

部署 JSF 复合组件以供共享使用

JSF 2 复合组件渲染问题

JSF拒绝处理深层嵌套的复合组件。不,真的:“JSF1098:[...]这浪费了处理器时间[...]”

JSF 2.0 复合组件 - ajax 渲染参数 OUTSIDE 组件定义