Primefaces 复制 DOM 中的元素

Primefaces duplicating elements in the DOM

每次单击按钮或进入对话框时,我的 overlayPanel 都会在 DOM 中重复,例如,无法将简单的字段发送到后端。我花了很多时间试图查看它是否与 p:commandbutton process/update 相关,或者即使它与控制器相关的生命周期错误,甚至观看有关此处的讨论。

这是我的 VIEW 的一部分,下面是我的三个 overlayPanel

<ui:define name="formActionAppend">
        <p:commandButton
            value="#{nfesBundle.btnTransmitNFe}"
            styleClass="GreenButton RaisedButton"
            icon="fa fa-send"
            rendered="#{nfesController.btnTransmitEnabled}"
            action="#{nfesController.doNFeTransmission()}"
            update="formDialog"
            process="@this formDialog"
            onsuccess="crudController.markAsChanged()" />
        <p:commandButton
            id="btnCancelNFe"
            styleClass="RedButton"
            value="#{nfesBundle.btnCancelNFe}"
            icon="fa fa-ban"
            type="button"
            rendered="#{nfesCancellationController.btnCancelEnabled}"
            update="@(.onCancelRequest)"
            process="@this" />
        <p:overlayPanel
            for="btnCancelNFe"
            at="left top"
            my="left bottom"
            appendToBody="true">
            <p:panel
                header="#{nfesBundle.cancellationPanelTitle}"
                rendered="#{nfesCancellationController.btnCancelEnabled}"
                styleClass="onCancelRequest">
                <sm:row>
                    <sm:cell
                        container="100"
                        responsive="100"
                        styleClass="floatLabel">
                        <p:outputLabel
                            for="justification"
                            value="#{nfesBundle.cancelationInputJustification}" />
                        <p:inputTextarea
                            id="justification"
                            maxlength="255"
                            required="true"
                            value="#{nfesCancellationController.justification}" />
                    </sm:cell>
                </sm:row>
                <div class="clearfix" />
                <f:facet name="footer">
                    <p:commandButton
                        id="btnDoNFeCancellation"
                        action="#{nfesCancellationController.doCancellation()}"
                        process="@parent"
                        update="formDialog"
                        value="#{nfesBundle.btnDoNFeCancellation}"
                        icon="fa fa-check"
                        onsuccess="crudController.markAsChanged()" />
                </f:facet>
            </p:panel>
        </p:overlayPanel>
        <p:commandButton
            id="btnGenerateCCe"
            value="#{nfesBundle.btnGenerateCCe}"
            styleClass="OrangeButton"
            icon="fa fa-pencil-square-o"
            type="button"
            rendered="#{nfesCCeController.btnGenerateCCeEnabled}"
            update="@(.onCCeRequest)"
            process="@this" />
        <p:overlayPanel
            for="btnGenerateCCe"
            at="left top"
            my="left bottom"
            appendToBody="true">
            <p:panel
                header="#{nfesBundle.ccePanelTitle}"
                rendered="#{nfesCCeController.btnGenerateCCeEnabled}"
                styleClass="onCCeRequest">
                <sm:row>
                    <sm:cell
                        container="100"
                        responsive="100"
                        styleClass="floatLabel">
                        <p:outputLabel
                            for="correction"
                            value="#{nfesBundle.cceInputCorrection}" />
                        <p:inputTextarea
                            id="correction"
                            maxlength="1000"
                            required="true"
                            value="#{nfesCCeController.correction}" />
                    </sm:cell>
                </sm:row>
                <div class="clearfix" />
                <f:facet name="footer">
                    <p:commandButton
                        id="btnDoGenerateCCe"
                        action="#{nfesCCeController.doGenerateCCe()}"
                        process="@parent"
                        update="formDialog"
                        value="#{nfesBundle.btnDoGenerateCCe}"
                        icon="fa fa-check"
                        onsuccess="crudController.markAsChanged()" />
                </f:facet>
            </p:panel>
        </p:overlayPanel>
        <p:button
            target="_blank"
            styleClass="BlueTextButton RaisedButton"
            value="#{nfesBundle.btnDownloadDanfePDF}"
            href="#{nfesController.getLinkDownloadDanfePDF()}"
            rendered="#{nfesController.btnDownloadDanfeEnabled}"
            icon="fa fa-file-pdf-o" />
        <p:button
            target="_blank"
            styleClass="BlueTextButton RaisedButton"
            value="#{nfesBundle.btnDownloadNFeXML}"
            href="#{nfesController.getLinkDownloadNFeXML()}"
            rendered="#{nfesController.btnDownloadNFeEnabled}"
            icon="fa fa-download" />
        <p:commandButton
            id="btnEmailNFe"
            value="#{nfesBundle.btnEmailNFe}"
            styleClass="RaisedButton GreenButton"
            icon="fa fa-envelope-o"
            type="button"
            rendered="#{nfesEmailController.entity.authorized}"
            update="@(.onEmailRequest)"
            process="@this" />
        <p:overlayPanel
            for="btnEmailNFe"
            at="left top"
            my="left bottom"
            appendToBody="true">
            <p:panel
                header="#{nfesBundle.emailPanelTitle}"
                rendered="#{nfesEmailController.entity.authorized}"
                style="width:500px;"
                styleClass="onEmailRequest">
                <sm:row>
                    <sm:cell
                        container="100"
                        responsive="100"
                        styleClass="floatLabel">
                        <p:outputLabel
                            for="email"
                            value="#{nfesBundle.emailAddress}" />
                        <p:inputTextarea
                            id="email"
                            required="true"
                            value="#{nfesEmailController.email}" />
                    </sm:cell>
                </sm:row>
                <div class="clearfix" />
                <f:facet name="footer">
                    <p:commandButton
                        id="btnEmailSend"
                        styleClass="GreenButton RaisedButton"
                        action="#{nfesEmailController.sendMail()}"
                        process="@parent"
                        update="formDialog"
                        value="#{nfesBundle.btnEmailSend}"
                        icon="fa fa-check" />
                </f:facet>
            </p:panel>
        </p:overlayPanel>
        <p:button
            value="#{nfesBundle.btnSaleView}"
            styleClass="RaisedButton BlueTextButton"
            rendered="#{nfesController.NFCeFromSale.present or nfesController.NFeFromSale.present}"
            icon="fa fa-share"
            outcome="sale">
            <f:param
                name="saleId"
                value="#{nfesController.entity.sale.id}" />
        </p:button>
        <p:button
            value="#{nfesBundle.btnStockPurchaseView}"
            styleClass="RaisedButton BlueTextButton"
            rendered="#{nfesController.NFeFromStockPurchase.present}"
            icon="fa fa-share"
            outcome="stockPurchase">
            <f:param
                name="stockPurchaseId"
                value="#{nfesController.entity.stockPurchase.id}" />
        </p:button>
        <p:button
            value="#{nfesBundle.btnStockTransferView}"
            styleClass="RaisedButton BlueTextButton"
            rendered="#{nfesController.NFeFromStockTransfer.present}"
            icon="fa fa-share"
            outcome="stockTransfer">
            <f:param
                name="stockTransferId"
                value="#{nfesController.entity.stockTransfer.id}" />
        </p:button>
        <p:button
            value="#{nfesBundle.btnVaccineApplicationsView}"
            styleClass="RaisedButton BlueTextButton"
            rendered="#{nfesController.NFCeFromVaccineApplication.present or nfesController.NFeFromVaccineApplication.present}"
            icon="fa fa-share"
            outcome="vaccineApplication">
            <f:param
                name="vaccineApplicationId"
                value="#{nfesController.entity.vaccineApplication.id}" />
        </p:button>
        <p:button
            value="#{nfesBundle.btnDevolutionView}"
            styleClass="RaisedButton BlueTextButton"
            rendered="#{nfesController.NFeFromDevolution.present}"
            icon="fa fa-share"
            outcome="devolution">
            <f:param
                name="devolutionId"
                value="#{nfesController.entity.devolution.id}" />
        </p:button>
    </ui:define>

这是 overlayPanels 的三个控制器之一

package eprecise.sgv.server.fiscal.nfes;

import java.io.IOException;
import java.io.Serializable;
import java.util.Optional;

import javax.ejb.ConcurrentAccessTimeoutException;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;
import javax.net.ssl.SSLHandshakeException;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

import eprecise.sgv.server.core.infra.CacheOnRenderResponse;
import eprecise.sgv.server.core.util.FacesMessageUtil;
import eprecise.sgv.server.core.validation.HandleConstraintViolations;
import eprecise.sgv.server.fiscal.nfes.events.NFeCancelSyncUnauthorized;
import eprecise.sgv.server.fiscal.nfes.events.NFeCancellationEvent;
import eprecise.sgv.server.fiscal.nfes.transmission.NFeTransmissionChannel;


@Named
@RequestScoped
@HandleConstraintViolations
@CacheOnRenderResponse
public class NfesCancellationController implements Serializable {

    private static final long serialVersionUID = 1L;

    private @NotNull @Size(min = 15, max = 255) String justification;

    private final NfesController controller;

    private final NFeTransmissionChannel transmissionChannel;

    private final NFesRepository repository;

    public NfesCancellationController() {
        this.controller = null;
        this.transmissionChannel = null;
        this.repository = null;
    }

    @Inject
    public NfesCancellationController(final NfesController controller, final NFeTransmissionChannel transmissionChannel, final NFesRepository repository) {
        this.controller = controller;
        this.transmissionChannel = transmissionChannel;
        this.repository = repository;
    }

    public String getJustification() {
        return this.justification;
    }

    public void setJustification(final String justification) {
        this.justification = justification;
    }

    public void doCancellation() {
        this.controller.setEntity(this.repository.find(this.controller.getEntity()));
        if (this.isBtnCancelEnabled()) {
            try {
                this.controller.getEntity().cancel(this.transmissionChannel, this.justification);
                this.controller.getEntity().getLastEvent().ifPresent(e -> {
                    if (e instanceof NFeCancellationEvent) {
                        FacesMessageUtil.addInfoMessage("Cancelada com sucesso");
                    } else if (e instanceof NFeCancelSyncUnauthorized) {
                        final NFeCancelSyncUnauthorized unauthorized = (NFeCancelSyncUnauthorized) e;
                        FacesMessageUtil.addWarnMessage(String.format("Não cancelada por: %s", unauthorized.getDetails()));
                    } else {
                        FacesMessageUtil.addInfoMessage("Transmissão efetuada, veja mais detalhes no histórico");
                    }
                });
                this.repository.update(this.controller.getEntity());
            } catch (final ConcurrentAccessTimeoutException e) {
                FacesMessageUtil.addWarnMessage("Não foi possível transmitir, tente novamente em alguns instantes");
            } catch (final RuntimeException e) {
                if ((e.getCause() instanceof SSLHandshakeException) || (e.getCause() instanceof IOException)) {
                    FacesMessageUtil.addWarnMessage("Houve um erro de comunicação com a sefaz. Tente novamente em alguns instantes");
                } else {
                    throw e;
                }
            }
        } else {
            FacesMessageUtil.addErrorMessage("Não é possível cancelar a NFe");
        }
    }

    public boolean isBtnCancelEnabled() {
        return this.controller.isInViewMode() && Optional.ofNullable(this.controller.getEntity()).map(BaseNFe::isAllowedToCancel).orElse(false);
    }
}

注意:我尝试在overlayPanel中使用dynamic = true,错误消失了,但是我的css完全崩溃了。

注意²:我一直在进行其他测试,发现这段代码在某些机器上有效,而在其他机器上则无效。我尝试切换浏览器并发出相同的请求,但没有任何反应。我真的不知道还能做什么

我正在使用 Java 8 和 Primefaces 7

我没有看到我在表单中使用它,请将元素放在表单中。 'h'字母是因为它是一个jsf元素。

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:p="http://primefaces.org/ui">
    ...

    <h:form id="idForm">
    
     ...
    
    </h:form>

另请注意:

版本变更 6.2 -> 7.0

OverlayPanel: appendToBody has been removed. Use appendTo="@(body)" instead.

您可以查看更多信息here