我正在尝试使用 setPropertyActionListener
标签在我的后备 bean 中设置一个值。但是,它并没有像我预期的那样工作。
上下文:userService是我的支持Bean的一个实例,它包含一个int成员reqID。反过来,这是属于名为 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>
旨在将 HTTP 请求参数添加到<h:xxxLink>
和<h:xxxButton>
组件的结果,并在 <h:outputFormat>
中参数化消息格式。该<ui:param>
旨在将 Facelet 上下文参数传递给 <ui:include>
、<ui:decorate>
和 <ui:define>
。Mojarra有一个错误,它的行为也像没有范围<c:set>
。这不是有意的用法。
如果绝对有必要"别名"(长)EL 表达式,只需使用不带作用域的<c:set>
。
<c:set var="id" value="#{user.id}" />
不过把它放在<h:commandLink>
外面。同样在这个结构中,它有点奇怪。它不会使代码更好。我就省略了。
<f:setPropertyActionListener ... value="#{user.id}" />
另请参阅:
- 有条件地设置 ui:param
- JSF 中 <UI:param> 的范围是什么?
- 在 JSF 页中定义和重用 EL 变量
与具体问题无关,如果你使用的是 EL 2.2(就像你使用 JSF 2.2 一样,你无疑是因为它需要最少的 Servlet 3.0,这与 EL 2.2 齐头并进),那么只需将其作为 bean action 方法 参数传递而不会<f:setPropertyActionListener>
混乱。参见 a.o.在EL中调用直接方法或带有参数/变量/参数的方法,以及如何将所选行传递给dataTable中的命令链接?
<h:commandButton ... action="#{userService.toUserInfo(user.id)}">
在另一个不相关的注释中,这样的"查看用户"或"编辑用户"请求通常是幂等的。您最好为此使用<h:link>
(是的,带有<f:param>
)。参见 a.o.为实体创建大纲-细节页面,如何链接它们以及选择哪个 Bean 范围以及如何在 JSF 中导航?如何使URL反映当前页面(而不是上一个页面)。
哦,围绕<ui:repeat><li>
的<h:panelGrid>
在HTML角度中没有意义。摆脱它并改用<ul>
。另请参阅 HTMLDog HTML 初学者教程。