【问题标题】:p:inplace still toggle back when validation failsp:inplace 在验证失败时仍会切换回来
【发布时间】:2015-04-20 18:50:56
【问题描述】:

我是 PrimeFaces 的新手,当我尝试将 <p:inplace><f:facet> 用于多个输入字段时,即使验证失败,它仍然会切换回来。

代码如下:

<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>

因此,当我将 2 个输入字段留空时,它仍会切换回输出方面,而它应该与红色边框保持相同。 请帮帮我。谢谢。

【问题讨论】:

  • 您的代码看起来与PrimeFaces showcase 上显示的示例大不相同。他们使用标签和 inputText 而不定义方面。我看到在一些展示示例中使用了方面,但是如果您更密切地遵循示例,事情是否会按预期工作,即在其自己的inplace 组件中定义每个inputText?跨度>
  • 在 Primefaces 展示中他们仍然使用 ,您可以再次查看。这个想法是当我点击一个方面时,它会打开另一个方面。
  • 是的,我看到他们正在使用构面,但他们没有按照您尝试的方式使用构面。命名方面是组件 API 的一部分:它们的使用受限于 API 设计者的意图。例如,dataTable 可以有一个名为“header”和“footer”的构面,但组件作者决定如何处理这些构面。由于 PrimeFaces 展示没有显示将多个输入组件嵌套在名为“input”的 facet 中的示例,因此您无法保证它会按照您希望的方式运行。

标签: jsf primefaces edit-in-place


【解决方案1】:

我认为 inplace.isValid() 中存在与使用构面相关的错误,因为我看到了同样的问题。这是 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");

    // ...
}

您可以在此处查看完整代码:https://github.com/primefaces/primefaces/blob/master/src/main/java/org/primefaces/component/inplace/InplaceRenderer.java

查看 InplaceTemplate 中的 isValid,它看起来只尝试验证 inplace 的直接子代,并且不会通过其其他后代向下递归(除非 getFacetsAndChildren 将后代树变平,我现在正在研究)。由于构面不是 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;
}

您可以在https://github.com/primefaces/primefaces/blob/master/src/main/java-templates/org/primefaces/component/inplace/InplaceTemplate.java查看完整代码

我不知道除了提交错误之外还有其他解决方案。

编辑

<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" />

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

【讨论】:

  • 我仍然不认为这是任何一种“错误”;这是对 API 的误解和误用。 PrimeFaces 展示或文档中没有任何内容表明支持 OP 的使用。命名方面是组件 API 的一部分。您所发现的只是 API 不支持您想要的功能。就好像您尝试将命名的 Facet“侧边栏”添加到数据表:它不会正常工作。
  • 根据BalusC,一个Facet只能有one child,这反映了Facet的正确使用,这是一种向组件提供额外信息的方式。
  • 是的,我的编辑旨在说明这一点。我们尝试添加多个字段和其他组件,以及在面板等其他容器内嵌套组件,所有这些都具有相同的结果。这可能不是一个错误,但它是一个不幸的限制。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-05
  • 2018-07-24
  • 1970-01-01
  • 1970-01-01
  • 2019-05-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多