仅在验证成功时渲染组件
Posted
技术标签:
【中文标题】仅在验证成功时渲染组件【英文标题】:Render a component only when validation success 【发布时间】:2015-12-03 16:10:30 【问题描述】:在 JSF 2.X 中,是否可以仅在验证成功时才渲染组件?
在我的申请中,我有许多必须填写的字段。这些数据可以通过搜索键从 WebService 导入。
当用户输入有效的搜索键时,系统会搜索其他字段并使用新值呈现它们。但是当用户输入不存在的键(或任何其他验证错误)时,服务器会生成验证错误,但仍会呈现字段,从而丢失已填充的所有数据。
我需要的是用户可以执行查询,并且如果查询没有返回结果,这不会影响他已经输入的任何数据。
下面是一个代码示例。因此,如果用户填写了 updateThisOnSuccess 中的字段,并且在尝试查询但未成功后,填写的值不会丢失。
<h:inputText value="#controller.searchWebService" >
<f:ajax execute="@this" render="updateThisOnSuccess messages" />
</h:inputText>
<h:panelGroup id="updateThisOnSuccess">
<h:inputText value="#controller.field" />
<!-- other fields -->
</h:panelGroup>
提交字段值以运行搜索似乎也不是一个选项,因为这将导致需要验证 updateThisOnSuccess 中的字段。
注意:我看到@BalusC 给the answer 提供了一个类似的问题,但这与我想知道的不同,为什么在这种情况下,总是呈现 foo-holder 并且 foo 是条件反射。这不是我的情况,因为这种方法会使控件在验证失败时不会出现。
【问题讨论】:
你的问题有点啰嗦,但我猜你基本上想要rendered="#not empty controller.searchWebService"
?毕竟,这只是在rendered
属性中准确指定所需条件的问题。
打扰一下。我试过了,但英语不是我的母语。我需要的不是那个。如果 controller.searchWebService 上的验证失败,我需要维护 panelGroup updateThisOnSuccess 中 input[text]、select 等中输入的值。 如果验证通过,则必须使用新值重新呈现它们。换句话说,就好像 Ajax 是这样的: Validation OK <f:ajax execute="@this" render="updateThisOnSuccess messages" />
Validation Failed <f:ajax execute="@this" render="messages" />
【参考方案1】:
试试这个
<h:panelGroup id="updateThisOnSuccess">
<ui:fragment rendered="#not facesContext.validationFailed">
<h:inputText value="#controller.field" />
<!-- other fields -->
</ui:fragment>
</h:panelGroup>
【讨论】:
【参考方案2】:请试试这个。要求是您必须使用 Bean Validation 实现模型验证,并且如果需要,搜索字段必须实现 JSF 验证。 如果您写“123456”,则返回数据,否则不返回任何内容并打印一条消息。
支持 bean:
@Named
@ViewScoped
public class yourBean implements Serializable
private static final long serialVersionUID = 1L;
@Size(min=2)
private String field01;
private String searchWebService;
public void saveF()
System.out.println("save");
public void searchWebServiceF()
Boolean successWS = ("123456").equals(this.searchWebService);
if(successWS)
this.setField01("WS data");
else
FacesContext.getCurrentInstance().
addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "WS fails", ""));
public String getSearchWebService()
return searchWebService;
public void setSearchWebService(String searchWebService)
this.searchWebService = searchWebService;
public String getField01()
return field01;
public void setField01(String field01)
this.field01 = field01;
在您的页面中:
<h:form id="form01">
<h:messages id="message"/>
<h:inputText id="wsid" value="#pruebasBorradorBean.searchWebService">
<f:validateLength maximum="6"/>
<f:ajax execute="@form" render="@form" listener="#pruebasBorradorBean.searchWebServiceF()" />
</h:inputText>
<h:panelGroup id="thedata">
<h:inputText value="#pruebasBorradorBean.field01">
<f:validateBean disabled="#param['javax.faces.source']!='form01:save'"/>
</h:inputText>
<!-- other fields -->
</h:panelGroup>
<h:commandButton id="save" value="submit">
<f:ajax render="thedata message" execute="@this thedata" listener="#pruebasBorradorBean.saveF()"/>
</h:commandButton>
</h:form>
【讨论】:
太棒了!在我的示例中,根据要求,您的代码运行良好。但在我的实际应用中,other fields 有很多Converters,例如Integer 和Date。你能解释一下如果 field01 是 PruebasBorradorBean 中的 Integer 怎么办?如果用户输入了无效字符,我可以像禁用 Validator 一样“禁用 Converter”吗?在我的测试中,最后一个测试用例不起作用,因为如果用户尝试使用 field01 中的无效字符搜索 WebService,它将指责转换错误。【参考方案3】:您可以更改将在渲染阶段处理的组件,更改位于getRenderIds() 的PartialViewContext 的集合。根据to documentation,这个集合是可变的。
FacesContext.getCurrentInstance().getPartialViewContext().getRenderIds().remove("formName:updateThisOnSuccess");
为了测试这个解决方案,我使用了这个控制器:
@Named
@ViewScoped
public class Controller implements Serializable
private static final long serialVersionUID = 1L;
private final static List<String> LIST_VALID_WEB_SERVICE_SEARCHS =
Arrays.asList(new String[] "foo", "bar");
private String webServiceParameter;
private Integer field01;
public void searchWebService()
if (LIST_VALID_WEB_SERVICE_SEARCHS.contains(getWebServiceParameter()))
setField01(123);
else
FacesContext facesContext = FacesContext.getCurrentInstance();
facesContext.getPartialViewContext().getRenderIds().remove("formFields");
FacesMessage facesMessage = new FacesMessage("Search not found in WebService.");
facesMessage.setSeverity(FacesMessage.SEVERITY_ERROR);
facesContext.addMessage("formName:searchWebService", facesMessage);
public void submit()
System.out.println("submitted");
// Getters and Setters
并使用了这个视图:
<h:form id="formSearch">
<h:inputText id="webServiceParameter" value="#controller.webServiceParameter">
<f:ajax execute="@this" render="formFields messages" listener="#controller.searchWebService" />
</h:inputText><br />
</h:form>
<h:form id="formFields">
<h:inputText id="field01" value="#controller.field01" required="true">
<f:validateLongRange minimum="2" maximum="345" />
</h:inputText><br />
<!-- other fields -->
<h:commandButton value="submit" action="#controller.submit">
<f:ajax render="@form messages" execute="@form" />
</h:commandButton>
</h:form>
<h:messages id="messages" />
【讨论】:
能否在WS成功后编写额外的代码模拟模型更新?你看过我的解决方案了吗? @lametaweb 我已经编辑了我的答案以满足您的评论。 好的。我认为这是一个非常好的解决方案。 @BalusC 你说这个问题很啰嗦。你认为这个解决方案是重复的答案,还是相反地在场景中加入了新的东西?【参考方案4】:你可以这样做:
<f:ajax execute="@this" render="#controller.success message"/>
其中success
是一个字符串属性,如果 WS 失败则为空,否则为“updateThisOnSuccess”。
或者您可以摆脱用于通知用户 WS 失败的 JSF 验证机制。想一想,这并不是对模型的真正验证。您可以使用支持 bean 中的布尔标志属性在 WS Id 字段旁边以红色或类似的颜色绘制一个图标。
【讨论】:
请先测试代码,然后再作为答案。如果您无法从头顶判断给定的代码是否有效,最好发表“试试这个”评论。以上是关于仅在验证成功时渲染组件的主要内容,如果未能解决你的问题,请参考以下文章