我正在尝试使用用户帐户实现表格,管理员可以对其进行修改。我使用primefaces(2.2)DataTable组件和cellEditor。
我有onRowEditListener,它使用manageUsers.onEditRow()方法通过UserDAO对象持久保存数据库中的更改。
加载页面并更新表格单元格后 - 数据库中的数据更改正确。不幸的是,当我尝试再次更新上一行时 - (UserDAO)event.getObject();
返回旧对象(第一次更改后的那个)并且数据不会更新。
当我重新加载页面(F5)和编辑行时 - 数据会正确更改。
如何在不重新加载页面的情况下更新表格或如何获得最新版本的用户?
使用Primefaces 2.2,JSF 2.1,Glassfish 3.1
页:
<p:column headerText="login" filterBy="#{u.user.login}" filterMatchMode="contains" style="width:150px">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{u.user.login}" />
</f:facet>
<f:facet name="input">
<h:form>
<p:inputText value="#{u.user.login}" />
</h:form>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="email" filterBy="#{u.user.email}" filterMatchMode="contains" style="width:150px">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{u.user.email}" />
</f:facet>
<f:facet name="input">
<h:form>
<p:inputText value="#{u.user.email}" />
</h:form>
</f:facet>
</p:cellEditor>
</p:column>
//... other fields
<p:column headerText="Options">
<p:rowEditor />
</p:column>
</p:dataTable>
</h:form>
使用ApplicationScope(CDI)ManageBean
@Named
@ApplicationScoped
public class ManageUsers implements Serializable {
@Inject
/** Inject database */
private DB db;
/** List with all leaked data which is loaded from database */
private List<UserDAO> users;
private User selectedUser;
private SelectItem[] manufacturerOptions;
public ManageUsers() {
manufacturerOptions = createFilterOptions();
}
public SelectItem[] getManufacturerOptions() {
return manufacturerOptions;
}
public User getSelectedUser() {
return selectedUser;
}
public void setSelectedUser(User selectedUser) {
this.selectedUser = selectedUser;
}
/** List of users loaded from database */
public void getDataFromDatabase() {
try {
users = db.getUserList();
if (users == null) {
throw new Exception("Pusta lista użytkowników");
}
} catch (Exception ex) {
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR,
"Nie można wyświetlić tabeli wyników",
"Nie udało się pobrać danych, prosimy spróbować ponownie później.");
FacesContext.getCurrentInstance().addMessage(null, message);
}
}
/**
* Get list of leaked Data.
* If list is null then getDataFromDatabase method is used.
* @see DataExplorer.getDataFromDatabase()
*/
public List<UserDAO> getUsers() {
if (users == null) {
getDataFromDatabase();
}
return users;
}
private SelectItem[] createFilterOptions() {
SelectItem[] options = new SelectItem[3];
options[0] = new SelectItem("", "-select-");
options[1] = new SelectItem("true", "Admins");
options[2] = new SelectItem("false", "Users");
return options;
}
public void onEditRow(RowEditEvent event){
UserDAO userDAO = (UserDAO)event.getObject();
try {
userDAO.update();
} catch (UserDAOException ex) {
Log.logger.error("User not edited,"+ex);
}
//getDataFromDatabase();
}
}
答案 0 :(得分:4)
您总是会返回一个新列表,这是JSF中众所周知的不良做法,在getter中获取数据。在JSF生命周期中可能会多次调用getter。将用户列表缓存在变量中,最好使用视图范围。
内联编辑/更新实际上有效但您每次都返回一个新列表而丢失更新的模型。
答案 1 :(得分:1)
我不知道我是否真的了解您的问题,但您可以轻松更新您的表格,甚至可以更好地更新您的表单,但是实现了带有更新属性的commandButton:
我们假设您有一个表单,并且它的ID是myTableForm
,然后在该表单中您拥有dataTable组件和commandButton组件。此按钮将如下所示:
<p:commandButton ajax='true' value='PersistData' update='myTableForm' action='if really needed' />
只有在需要时才能参考动作方法。否则,此按钮将仅通过实现ajax请求来更新整个表单。默认情况下,Ajax是true,但我明确地在那里添加了该属性。
当然你可以有另一个逻辑设计......你不必实现一个按钮来做到这一点,你可以有一些ajax监听器,一些将在页面加载时触发的javascript函数,编辑单元格等...我选择了一个commandButton,因为它是了解逻辑的最简单方法......
如果这真的是你想要的,请告诉我。
答案 2 :(得分:1)
问题解决了。 p:inputText = _ =
附近有额外的h:形式