Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jsf “Primefaces”对话框正在渲染两次_Jsf_Jsf 2_Dialog_Primefaces_Modal Dialog - Fatal编程技术网

Jsf “Primefaces”对话框正在渲染两次

Jsf “Primefaces”对话框正在渲染两次,jsf,jsf-2,dialog,primefaces,modal-dialog,Jsf,Jsf 2,Dialog,Primefaces,Modal Dialog,我已经创建了一个ui:component,可以像弹出窗口一样使用,所以我可以使用这个模板的标准创建很多弹出窗口。 该组件只是一个带有两个按钮(取消和提交)的弹出窗口,以及一个可以覆盖的内容,如您在此处看到的: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="h

我已经创建了一个ui:component,可以像弹出窗口一样使用,所以我可以使用这个模板的标准创建很多弹出窗口。 该组件只是一个带有两个按钮(取消和提交)的弹出窗口,以及一个可以覆盖的内容,如您在此处看到的:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.prime.com.tr/ui">
<ui:component>
<p:dialog widgetVar="#{idPopup}" id="#{idPopup}" modal="#{popup.modal}"
    draggable="#{popup.modal}"
    rendered="#{popup.visivel}" visible="#{popup.visivel}"
    closeOnEscape="false" closable="false" header="#{titulo}"
    resizable="false" styleClass="autoWidthDialog" showEffect="fade"
    hideEffect="fade">
    <h:panelGroup style="width:100%">
        <p:focus />
        <ui:insert name="conteudo">Nenhum conteúdo definido!</ui:insert>
        <h:panelGrid id="#{idPopup}PainelMensagens" style="width:100%">
            <p:messages />
        </h:panelGrid>
        <ui:insert name="barraDeBotoes">
            <h:panelGroup layout="block" style="width:100%">
                <p:commandButton value="CANCELAR" immediate="true" update="@form"
                    style="float:right" action="#{controladorPopup.fechar}"
                    onclick="#{idPopup}.hide();" />
                <p:commandButton value="OK" style="float:right"
                    update="@form formAlerta"
                    action="#{controladorPopup.submit}"
                    process="@form" />
            </h:panelGroup>
        </ui:insert>
    </h:panelGroup>
</p:dialog>
</ui:component>
</html>

涅恩·康托多·迪尼多!
当我试图提交表单而不填写必填字段时,就会出现问题。正确的行为只是再次显示带有消息的弹出窗口,但对话框呈现两次,一次显示消息,一次不显示消息。 您可以在此处看到此行为:

这是此模板的一种用法:

<ui:composition template="../templates/popupSubmit.xhtml">
<ui:param name="titulo" value="Buscar pessoa" />
<ui:param name="popup" value="#{modeloPopupBuscaPessoa}" />
<ui:param name="controladorPopup"
    value="#{controladorPopupBuscaPessoa}" />
<ui:define name="conteudo">
    <h:panelGroup>
        <h:panelGrid columns="2">
            <h:outputLabel value="Tipo de cadastro:" style="float:none" />
            <h:selectOneMenu value="#{controladorSugestaoPessoa.tipoCadastro}"
                immediate="true">
                <f:selectItems value="#{carregadorTipoCadastro.itens}" />
                <f:ajax event="change" immediate="true" />
            </h:selectOneMenu>
        </h:panelGrid>
        <h:outputText value="Buscar por:" />
        <h:selectOneRadio value="#{controladorSugestaoPessoa.tipoBusca}"
            immediate="true">
            <f:selectItems value="#{carregadorTipoBuscaPessoa.itens}" />
            <f:ajax event="change" immediate="true" />
        </h:selectOneRadio>
        <p:autoComplete value="#{modeloPopupBuscaPessoa.itemSelecionado}"
            forceSelection="true" maxResults="10" queryDelay="500" 
            completeMethod="#{controladorSugestaoPessoa.atualizarSugestoes}"
            var="pessoa" itemLabel="#{pessoa.label}" itemValue="#{pessoa}"
            converter="#{conversorSelectItem}" />
    </h:panelGroup>
</ui:define>
</ui:composition>

以下是一些用途:

<h:form id="cadastroPessoa">
    <ui:include
        src="resources/components/popups/modulo_cadastro/popupNovoCadastroPessoa.xhtml">
        <ui:param name="idPopup" value="popupNovoCadastroPessoa" />
    </ui:include>
    <ui:include
        src="resources/components/popups/modulo_cadastro/popupCadastroPessoa.xhtml">
        <ui:param name="idPopup" value="popupEdicaoCadastroPessoa" />
    </ui:include>
    <ui:include
        src="resources/components/popups/modulo_cadastro/popupBuscaPessoa.xhtml">
        <ui:param name="idPopup" value="popupBuscaCadastroPessoa" />
    </ui:include>
</h:form>

<h:form id="cadastroProduto">
    <ui:include
        src="resources/components/popups/modulo_cadastro/popupCadastroProduto.xhtml">
        <ui:param name="idPopup" value="popupNovoCadastroProduto" />
    </ui:include>
</h:form>


有人能告诉我为什么会发生这种情况吗?

我会检查您的widgetVar=“#{idPopup}”id=“#{idPopup}”在提交表单之前和之后是否相同。可能它已更改,primefaces认为它不再存在,并创建了一个新的。

oncomplete
属性添加到提交按钮中,并让它隐藏对话框:

<p:commandButton value="OK" style="float:right"
                 update="@form formAlerta"
                 action="#{controladorPopup.submit}"
                 process="@form"
                 oncomplete="#{idPopup}.hide();"/>

我在primefaces论坛上发布了同样的问题(就像Tommy Chan告诉我的),有人回答了这个问题:

您可能将对话框放置在正在更新的表单中,该表单为nono。永远不要只更新对话框中的内容

我一直在尝试这样做,直到我看到我所有的对话框都有来自服务器的“呈现”属性(只看到第一个xml),我在这个应用程序中有很多对话框,其中一些与其他对话框有关系(在服务器上),最后一个对话框在同一个表单上

我做了一些不同的事情,我只创建了以下javascript代码:

function removerDialogo(id) {
   setTimeout(function() {
       removerDialogoAposIntervalo(id);
   }, 100);  
}

function removerDialogoAposIntervalo(id) { 
   id = id.replace(':', '\\:');
   jQuery('div.ui-dialog')
       .find('#' + id)
       .parent().eq(1)
       .remove(); 
}
并将此对话框称为“onShow”属性:

<p:dialog widgetVar="#{idPopup}" id="#{idPopup}" modal="#{popup.modal}"
    draggable="#{popup.modal}" rendered="#{popup.visivel}"
    visible="#{popup.visivel}" closeOnEscape="false" closable="false"
    header="#{titulo}" resizable="false" styleClass="autoWidthDialog"
    showEffect="fade" hideEffect="fade" onShow="removerDialogo(this.id)">

我不喜欢这样做,但我找不到更好的方法来解决这个问题。。。
如果有人给我一个更好的解决方案,我将不胜感激

正如我在primefaces论坛上所说,您正在使用其中的对话框更新表单。。。您需要将对话框放在表单之外,并单独更新它们。如果需要在对话框中使用表单,请将其放置在对话框中:

   <p:dialog><p:form> </p:form> </p:dialog>


将表单放在对话框中并不是解决问题的最佳方法,如果您使用IExplorer访问应用程序,对话框将无法使用这种方法

在我的情况下,我无法使用oncomplete)方法隐藏对话框,因为它必须关闭某些业务逻辑

我在我的案例中使用了UI上的primefaces选项卡。每次我浏览标签,然后点击出现对话框的按钮,我的对话框数量就成比例增加 因此,我使用简单的jquery脚本从UI中删除了所有重复对话框 电子用户界面

函数移除的重复对话框(dialogId){
\\一般来说,我们所有的组件都有:我们必须
\\将“:”替换为“\\:”(应用转义字符)
dialogId=dialogId.replace(/\:/g,\\:');
var dialogs=jQuery(“div[id=“+dialogId+”]”);
var numOfDialogs=dialogs.length;
numOfDialogs=numOfDialogs-1;
for(var i=0;i
我在对话框中遇到了同样的问题,解决方案是将commandButton的更新放在对话框组件上,该按钮显示对话框组件的特定id而不是表单id,解决方案如下所示:

    <p:dialog id="dialogId">
        <p:commandButton value="OK" style="float:right"
             update="@form dialogId"
             action="#{controladorPopup.submit}"
             process="@form"/>
    </p:dialog>

这是一个可怕的错误,没有官方答案

我正在使用一个对话框来渲染谷歌地图。我处理这个bug的方法(使用JQuery)是计算primefaces:dialog.onShow上DOM中“.map”元素的数量。。。然后,我选择:last.map实例rendered(或者在您的示例中,选择您正在使用的任何内容类),并选择.remove()包含该实例的对话框:

标记(近似值):


如果你是一个虐待狂,你可以,很舒服地,把它变成一句台词。。。我认为这是一个错误。“关闭”按钮会彻底破坏对话框。

我已经尝试过这个选项,对话框打开两次,但立即关闭。两个对话框的id相同:cadastroEmpresa:PopupNovoCadastroEmpresa可能会在primefaces论坛上提问…那里的用户反应非常迅速。primefaces widgetVar和JSF id不得相同。我在论坛的某个地方读到了擎天柱自己发布的一条“黄金”法则。现在找不到。是否也可以在模板和模板客户端中发布与此片段相关的代码?不确定这是否是整个问题的原因,但将对话框设计为包含文件有点奇怪。标记文件或复合组件是更明智的选择。此外,该对话框还应该有自己的
,并且不能放在任何
中。在提交对话框中的字段时,您不希望以相同的形式提交/处理对话框外部页面中的所有其他字段。哈!这是我在primefaces论坛上的评论。我之所以这么说是因为你的更新上写着@form。。。你的对话框周围没有表单标签。。。这意味着它在你的对话之上。。。这意味着你的对话框是在表单中。修复了这个问题,在我的例子中,我更新了所有表单,而不仅仅是组件。导致对话框出现两次。嗨,Rafael,正如我所说的,我尝试过这种方法,但是应用程序非常大,这种方法不能以通用的方式用于该组合。这是因为一些对话的关系。为此,我需要更改所有应用程序逻辑。。。但我肯定下次会以正确的方式实施:)谢谢。@brevleq
    <p:dialog id="dialogId">
        <p:commandButton value="OK" style="float:right"
             update="@form dialogId"
             action="#{controladorPopup.submit}"
             process="@form"/>
    </p:dialog>
<pri:dialog onShow="popupOpen();" etc...>
    <div id="map" class"map"></div>
</pri:dialog>
function onShowDialog(){
    if($(".map").length > 1){
        $cull = $(".map:last");
        $cull.closest(".ui-dialog").remove();
    }
}