1

在 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 对类似问题的回答,但这与我想知道的不同,在这种情况下,总是呈现foo-holder并且foo是调节的。这不是我的情况,因为这种方法会使控件在验证失败时不出现。

4

4 回答 4

1

尝试这个

<h:panelGroup id="updateThisOnSuccess">
    <ui:fragment rendered="#{not facesContext.validationFailed}">
        <h:inputText value="#{controller.field}" />
        <!-- other fields -->
    </ui:fragment>
</h:panelGroup>
于 2015-09-11T16:09:44.243 回答
0

您可以更改将在渲染阶段处理的组件,更改PartialViewContext的getRenderIds()处的 Collection 。根据文档,Collection 是 mutable

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" />
于 2015-09-08T22:05:53.607 回答
0

请试试这个。要求是您必须使用 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>
于 2015-09-08T23:50:15.670 回答
-1

你可以这样做:

<f:ajax execute="@this" render="#{controller.success} message"/>

wheresuccess是一个 String 属性,如果 WS 失败,它将为空,如果不是,则为“updateThisOnSuccess”。

或者,您可以摆脱用于通知用户 WS 失败的 JSF 验证机制。想一想,这并不是对模型的真正验证。您可以使用支持 bean 中的布尔标志属性在 WS Id 字段旁边以红色或类似的颜色绘制一个图标。

于 2015-09-08T08:01:35.133 回答