我有一个dataTable,其中包含项目列表和用于选择要编辑的项目的复选框。勾选一个项目并单击编辑按钮,会弹出一个包含字段、更新和取消按钮的组件。事情是这样的。
- 对话框出现
- 我清空所有字段并单击UPDATE,由于所有字段都是空的,因此会显示所需消息,数据不会保存
- 单击CANCEL,对话框消失
- 再次单击并编辑同一项目
- 某些字段未显示。我检查了数据表和数据库,该项目的数据仍然存在。只是第二次没有显示在编辑对话框上。
我注意到,没有显示的字段只是那些具有NULL属性的字段。NOT NULL字段可以。我想知道这是否与会话有关。(对所有组件使用Primefaces)
编辑对话框的代码
<p:dialog header="#{bundle.Edit}" modal="true" widgetVar="editDialog" resizable="false">
<h:form id="edit-form">
<p:messages id="edit-error" autoUpdate="true" closable="true"/>
<h:outputLabel value="#{bundle.Name}" for="name" /><span class="required">*</span>
<p:inputText id="name" value="#{controller.selected.name}" required="true" requiredMessage="#{bundle.Name} #{bundle.FieldIsRequired}" maxlength="45"/>
<h:outputLabel value="#{bundle.Input}" for="input" /><span class="required">*</span>
<h:selectOneRadio id="input" value="#{controller.selected.input}" required="true" requiredMessage="#{bundle.Input} #{bundle.FieldIsRequired}">
<f:selectItem itemLabel="◯ " itemValue="0" />
<f:selectItem itemLabel="☓ " itemValue="1" />
</h:selectOneRadio>
<h:outputLabel value="#{bundle.IsOption}" for="isOption" /><span class="required">*</span>
<h:selectOneRadio id="isOption" value="#{controller.selected.isOption}" required="true" requiredMessage="#{bundle.IsOption} #{bundle.FieldIsRequired}">
<f:selectItem itemLabel="◯ " itemValue="0" />
<f:selectItem itemLabel="☓ " itemValue="1" />
</h:selectOneRadio>
<h:outputLabel value="#{bundle.Remark}" for="remark" />
<p:inputTextarea id="remark" value="#{controller.selected.remark}"/>
<p:commandButton action="#{controller.update()}"
value="#{bundle.Save}"
actionListener="#{controller.prepareList()}"
oncomplete="handleEditDialog(xhr, status, args)"
update=":form:datatable :edit-form:edit-error"
/>
<p:commandButton value="#{bundle.Cancel}"
onclick="editDialog.hide(); reset();"
type="button"/>
</h:form>
</p:dialog>
更新功能的代码
public String update() {
RequestContext context = RequestContext.getCurrentInstance();
try {
current.setUpdateDate(new Date());
Map<String, Object> param = JsfUtil.getExternal().getSessionMap();
int createUser = (Integer) param.get("LOGIN_ID");
Account account = accountFacade.find(createUser);
current.setUpdateUser(account);
getFacade().edit(current);
search();
prepareList();
JsfUtil.addSuccessMessage(ResourceBundle.getBundle(JsfUtil.getSessionBundle()).getString("Updated"));
updateOk = true;
current = null;
context.addCallbackParam("updated", true);
return "";
} catch (Exception e) {
if (e.getCause().getCause().getMessage().contains("uk_")) {
JsfUtil.addErrorMessage("edit-form:edit-error",JsfUtil.getResourceString("Duplicate"));
context.addCallbackParam("updated", false);
} else {
JsfUtil.addErrorMessage(e, ResourceBundle.getBundle(JsfUtil.getSessionBundle()).getString("PersistenceErrorOccured"));
context.addCallbackParam("updated", false);
}
return null;
}
}
根据您所描述的内容,我认为以下场景正在发生。当您看到表单并删除所有字段并点击save时,没有验证器的组件实际上正在覆盖您的bean以前的一些属性值。这就是为什么当你重新加载它进行第二次编辑时,你会注意到所有附加了验证器的组件(例如required=true)都出现了,但没有验证器的组件是空白的。实际上,您实际上正在进行部分更新。您实际需要做的是根据需要标记所有字段,以避免出现该问题。
我的队友刚刚找到了这个补丁。控制器上有一个由NetBeans生成的函数,名为prepareList()。
public String prepareList() {
recreateModel();
return "";
}
private void recreateModel() {
items = null;
}
基本上,我们在update()函数的catch块上添加了这个。它在每次更新失败后调用,并重新创建模型。该错误的存在是因为该字段在更新失败后保持了没有值的状态。