Jsf p:inplace在验证失败时仍然切换回

Jsf p:inplace在验证失败时仍然切换回,jsf,primefaces,edit-in-place,Jsf,Primefaces,Edit In Place,我不熟悉PrimeFaces,当我尝试将与一起用于多个输入字段时,即使验证失败,它仍会切换回原处 代码如下: <p:inplace editor="true"> <f:facet name="output"> <h:outputText value="Hello Inplace" /> </f:facet> <f:facet name="input"> <p:inputText value="#{myB

我不熟悉PrimeFaces,当我尝试将
一起用于多个输入字段时,即使验证失败,它仍会切换回原处

代码如下:

<p:inplace editor="true">
  <f:facet name="output">
    <h:outputText value="Hello Inplace" />
  </f:facet>
  <f:facet name="input">
    <p:inputText value="#{myBean.name}" required="true" />
    <p:inputText value="#{myBean.age}" required="true" />
  </f:facet>
</p:inplace>

因此,当我将两个输入字段留空时,它仍然切换回输出方面,而红色边框应该保持不变。
请帮帮我。谢谢。

我相信inplace.isValid()中有一个与facet的使用相关的bug,因为我看到了相同的问题。以下是InplaceRenderer中encodeMarkup方法的相关代码。正如您所看到的,确实期望输入和输出的命名方面

protected void encodeMarkup(FacesContext context, Inplace inplace) throws IOException {
    // ...

    boolean validationFailed = context.isValidationFailed() && !inplace.isValid();
    String displayStyle = validationFailed ? "none" : "inline";
    String contentStyle = validationFailed ? "inline" : "none";

    UIComponent outputFacet = inplace.getFacet("output");
    UIComponent inputFacet = inplace.getFacet("input");

    // ...
}
您可以在此处看到完整的代码:

查看InplaceTemplate中的isValid,它似乎只尝试对inplace的直接子级进行验证,而不会通过其其他子级递归(除非GetFacesAndChildren展平子级树,我现在正在研究)。因为facet不是EditableValueHolder的实例,所以它甚至不会对它们进行验证并返回true。下面是完整的isValid方法

public boolean isValid() {
    boolean valid = true;

    for(Iterator<UIComponent> it = this.getFacetsAndChildren(); it.hasNext();) {
        UIComponent component = it.next();
        if(component instanceof EditableValueHolder && !((EditableValueHolder) component).isValid()) {
            valid = false;
            break;
        }
    }

    return valid;
}
public boolean有效(){
布尔有效=真;
for(迭代器it=this.getFacetsAndChildren();it.hasNext();){
UIComponent=it.next();
if(EditableValueHolder&!((EditableValueHolder)组件的组件实例).isValid(){
有效=错误;
打破
}
}
返回有效;
}
您可以在上看到完整的代码

我不知道除了提交bug之外还有什么解决方案

编辑

<p:inplace id="inplace" editor="true">
    <f:facet name="output">
        <h:outputText value="#{bean.value}" />
    </f:facet>
    <f:facet name="input">
        <p:inputText id="input" value="#{bean.value}" required="true" requiredMessage="Required field message goes here" />
        <p:message for="input" />
    </f:facet>
</p:inplace>

将它更新为类似这样的东西使我们更接近,因此可能在facet中有多个组件是问题所在

<p:inplace id="inplace" editor="true">
    <p:ajax event="save" update="message" />
    <f:facet name="output">
        <h:outputText value="#{bean.value}" />
    </f:facet>
    <f:facet name="input">
        <p:inputText id="input" value="#{bean.value}" required="true" requiredMessage="Required field message goes here" />
    </f:facet>
</p:inplace>
<p:message id="message" for="input" />


不幸的是,在点击cancel时重置字段和消息仍有一点不尽如人意,但至少对我们来说,这是朝着正确方向迈出的一步。

您的代码看起来与屏幕上显示的示例大不相同。他们使用标签和inputText,但没有定义面。我看到一些showcase示例中使用了facet,但如果您更仔细地遵循示例,即在其自己的
inplace
组件中定义每个
inputText
,事情是否会按预期进行?在他们仍然使用的Primefaces showcase中,您可以再次检查。我的想法是,当我点击一个方面时,它会打开另一个方面。是的,我看到他们正在使用方面,但他们没有像你尝试的那样使用方面。命名方面是组件API的一部分:它们的使用受API设计者意图的约束。例如,
dataTable
可以有一个名为“header”和“footer”的方面,但由组件作者决定如何处理这些方面。由于PrimeFaces showcase没有显示将多个输入组件嵌套在一个名为“input”的方面中的示例,因此您无法保证它将按照您希望的方式运行;这是对API的误解和误用。PrimeFaces showcase或文档中没有任何内容表明支持OP的使用。命名方面是组件API的一部分。您所发现的只是API不支持您想要的功能。这就好像你试图将命名的Facet“边栏”添加到一个数据表中:它不会只起作用。根据BalusC的说法,Facet只能有,这反映了Facet的正确使用,这是向组件提供额外信息的一种方式。是的,我的编辑就是为了说明这一点。我们尝试添加多个字段和其他组件,以及将组件嵌套在其他容器(如面板)中,所有这些都得到了相同的结果。它可能不是一个bug,但它是一个不幸的限制。