此问题是前一个问题的后续问题"当禁用时,InputText值为null"但我无法添加评论。
当设置为true时,我正在使用jsf 2.2和disabled和readonly属性,当包含在表单中时,inputText和inputTextarea控件在合并对象时从数据库中的关联字段中删除数据,因为字段是从jsf页面返回对象时返回null。
在表单字段中设置这些属性的目的是在字段中显示数据,但不允许用户更改数据并将更改保存到表单中的其他字段。
除了将字段放在表单之外并使页面布局复杂化之外,还有什么方法可以实现。
格雷厄姆
答案 0 :(得分:1)
我解决了这个问题,这是因为我的页面控制器bean使用了@RequestScoped而不是@SessionScoped。
我正在做的是使用从当前产品对象传递到doEditProduct方法的数据表的编辑链接。
<h:dataTable id="viewProductsTable" value="#{productController.products}" var="_product"
styleClass="data-table" headerClass="table-header" rowClasses="table-row">
<h:column>
<f:facet name ="header">
<h:outputText value="Product Name" />
</f:facet>
<h:outputText value="#{_product.productName}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Goal"/>
</f:facet>
<h:outputText value="#{_product.goal}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Details"/>
</f:facet>
<h:outputText value="#{_product.description}"/>
</h:column>
<h:column>
<h:form>
<h:commandLink value="Edit" action="#{productController.doEditProduct(_product)}"/>
</h:form>
</h:column>
</h:dataTable>
productController.doEditProduct方法然后打开编辑页面
public String doEditProduct(Product product) {
this.product = product;
return "edit-product.xhtml";
编辑页面包含一个简单的编辑表单
<h:form id="addProductForm">
<h:panelGrid columns="2" columnClasses="top-alignment, top-alignment">
<h:outputLabel for="product-name" value="Product Name"/>
<h:outputText value="#{productController.product.productName}" id="product-name" />
<h:outputLabel for="goal" value="Goal" />
<h:inputTextarea value="#{productController.product.goal}" id="goal" rows="10" cols="100" />
<h:outputLabel for="details" value="Details" />
<h:inputTextarea value="#{productController.product.description}" id="details" rows="20" cols="100"/>
<f:facet name="footer">
<h:panelGroup style="padding-top: 15px; display: inline-block; float: right; white-space: nowrap">
<h:commandButton id="submit" value="Save" action="#{productController.updateProduct()}" class="button" />
<h:button id="Cancel" outcome="index.xhtml" value="Cancel" class="button"/>
</h:panelGroup>
</f:facet>
</h:panelGrid>
</h:form>
此时,产品数据显示在页面上。但是,单击保存按钮并运行更新方法
public String updateProduct() {
try {
log.log(Level.INFO, "Updating: {0}", product.getGoal());
productFacade.edit(product);
} catch (Exception e) {
log.log(Level.WARNING, e.toString());
String errorMessage = getRootErrorMessage(e);
FacesMessage m = new FacesMessage(FacesMessage.SEVERITY_ERROR, errorMessage, "could not update product");
facesContext.addMessage(null, m);
return "";
}
return "index.xhtml";
已禁用或只读的任何字段都设置为null。实际上,页面上任何位置的任何非输入字段都设置为null。
控制器类上的@RequestScope意味着该类正在重新实例化,因此存储在产品中的对象在PostConstruct方法中被分配了一个新对象。可编辑字段中的值已传输到此新对象,而不可编辑字段则设置为null。与数据库合并意味着删除了字段中的数据。
使用@SessionScoped意味着控制器bean在页面请求中继续存在。 (我需要提醒自己基本的网页生命周期)
希望这可以帮助其他有这种行为的人。
格雷厄姆