使用 f:param 值设置 f:setPropertyActionListener 值

Setting f:setPropertyActionListener value with a f:param value

我正在尝试使用 setPropertyActionListener 标记在我的支持 bean 中设置一个值。然而,它并没有像我预期的那样工作。

上下文:userService 是我的支持 bean 的一个实例,它包含一个 int 成员 reqID。这反过来又是属于 class 名为 User 的对象映射的关键。我正在尝试创建一个页面,该页面将列出用户的所有实例,并提供一个按钮来访问显示该特定用户信息的单独视图。为此,我尝试将 userService.reqID 设置为所选用户的 ID,以便它可以为下一个视图生成对该用户的引用(在调用 userService.toUserInfo 中完成)。

如果我使用下面的 xhtml 片段:

<ui:define name="content">
        <h:form>
            <h:panelGrid>
                    <ui:repeat value="#{userService.UserList.getUserList()}" var="user">
                        <li>
                            <h:outputText value="#{user.name}" />
                            <h:commandButton value="View details of #{user.name}" action="#{userService.toUserInfo}">
                            <f:param name="id" value="#{user.id}" />
                            <f:setPropertyActionListener target="#{userService.reqID}" value="#{id}"/>
                            </h:commandButton>

                        </li>
                    </ui:repeat> 
            </h:panelGrid>
        </h:form>
    </ui:define>

标签似乎无法正确评估 id,我得到了空指针异常。

早些时候,我尝试更改我的 setPropertyActionListenerTag,因此它显示为:

<f:setPropertyActionListener target="#{userService.reqID}" value="id"/>

这给了我一个错误,因为标签发送的是字符串 "id" 而不是参数的 int 值。

有没有办法强制f:setPropertyActionListener计算value下的表达式?或者是否有另一个标签可以让我这样做?

另外,ui:param在这里使用得当吗?

<f:param>(和<ui:param>)不是那样工作的。 <f:param> 的目的是在 <h:xxxLink><h:xxxButton> 组件的输出中添加 HTTP 请求参数,并在 <h:outputFormat> 中参数化消息格式。 <ui:param> 旨在将 Facelet 上下文参数传递给 <ui:include><ui:decorate><ui:define>。 Mojarra 有一个错误,它在没有范围的情况下也表现得像 <c:set>。这不是预期用途。

如果绝对需要 "alias" 一个(长)EL 表达式,只需使用不带作用域的 <c:set>

<c:set var="id" value="#{user.id}" />

虽然把它放在 <h:commandLink> 外面。同样在这个构造中,它有点奇怪。它不会使代码更好。我会忽略它。

<f:setPropertyActionListener ... value="#{user.id}" />

另请参阅:

  • Setting ui:param conditionally
  • what is the scope of <ui:param> in JSF?
  • Defining and reusing an EL variable in JSF page

与具体问题无关,如果您使用的是 EL 2.2(因为您使用的是 JSF 2.2,毫无疑问,因为它至少需要 Servlet 3.0,这与 EL 2.2 并驾齐驱),然后只需将其作为 bean 操作方法参数传递即可,不会造成 <f:setPropertyActionListener> 混乱。另见 a.o。 Invoke direct methods or methods with arguments / variables / parameters in EL and How can I pass selected row to commandLink inside dataTable?

<h:commandButton ... action="#{userService.toUserInfo(user.id)}">

另一个不相关的注释,这样的 "View user" 或 "Edit user" 请求通常是幂等的。为此,您最好使用 <h:link>(是的,使用 <f:param>)。另见 a.o。 Creating master-detail pages for entities, how to link them and which bean scope to choose and How to navigate in JSF? How to make URL reflect current page (and not previous one).

哦,<ui:repeat><li> 周围的 <h:panelGrid> 从 HTML 角度来看没有意义。摆脱它并使用 <ul> 代替。另见 HTMLDog HTML Beginner tutorial.