我正在创建一个JSF应用程序。我有一些来自数据库的项目(例如产品),我想创建一个用于编辑特定项目的JSF页面,即:
我在存储/传递正在编辑的项目的ID时遇到问题。我在示例JSF CarDemo应用程序中看到它们存储正在会话中查看的项目(汽车)。我不想这样做,因为我希望用户能够在不同的浏览器选项卡中编辑不同的元素。
我尝试了几种方法:
itemId
)GET参数,但是在编辑数据后很难返回项目页面(faces-config.xml中的to-view-id
字段只能包含常量) ,我仍然无法消除的问题是,如果在编辑了一些项目属性后我尝试保存它们并且验证(例如f:validateLength
)失败,页面将被重新加载,但正在编辑的项目的ID将丢失。我认为在创建Web应用程序(例如用户版,商店产品版)时这是非常标准的任务,因此肯定应该有一些解决方案。
提前致谢。
答案 0 :(得分:4)
相关信息:
请参阅this answer以获取允许在保留ID时进行编辑的示例代码(如果您使用的是JSP而不是Facelets,则该信息仍然适用)。有关您可能希望使用的其他一些技巧,请参阅this answer。有关在URL中保留参数的选项,请参阅this answer。
要解决您的问题,请创建一个请求范围bean来执行操作:
//pseudo-stubs
//request scope: #{editor}
public class Editor {
public Integer getId();
public void setId(Integer id);
public String save();
}
(您可以根据需要添加其他属性。)
通过faces-config
中的注入导航到页面时,从请求参数填充id:
<managed-bean>
<managed-bean-name>editor</managed-bean-name>
<managed-bean-class>foo.Editor</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>id</property-name>
<property-class>java.lang.Integer</property-class>
<value>#{param.id}</value>
</managed-property>
//etc
使用隐藏字段保留ID:
<h:inputHidden value="#{editor.id}" />
<h:commandLink action="#{editor.save}" value="save" />
每次提交表单时,都会发送此值;如果验证失败,隐藏字段仍将使用id值呈现。如果验证成功,则editor
bean将在调用save
之前使用id填充。
答案 1 :(得分:3)
Tomahawk的t:saveState
完全符合您的要求。只需在页面中添加类似内容:
<t:saveState value="#{bean.item.id}" />
或者如果您想要涵盖所有“未覆盖”项目值:
<t:saveState value="#{bean.item}" />
如果您不想出于某些未知原因添加其他组件库(我执行建议使用Tomahawk,它会在标准JSF实现之上添加更灵活的组件,例如t:dataList
,t:dataTable preserveDataModel="true"
,t:selectOneRadio layout="spread"
,t:inputFileUpload
,等等,您还可以使用标准<h:inputHidden>
组件将隐藏参数从请求传递到请求(它呈现{{1 }})。需要注意的是,在验证阶段失败时,您仍然会丢失值。但是,使用组件<input type="hidden">
代替binding
。
value
并且在JSF页面中具有以下相同形式:
private HtmlInputHidden itemId = new HtmlInputHidden();
private Item item = new Item();
public void editItem() { // Action method when selecting an item for edit.
itemId.setValue(item.getId());
}
public void saveItem() { // Action method when saving edited item.
item.setId((Integer) itemId.getValue());
}
希望这有帮助。