【问题标题】:Primefaces duplicating elements in the DOMPrimefaces 在 DOM 中复制元素
【发布时间】:2021-02-16 22:58:54
【问题描述】:

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

这是我的视图的一部分,下面有我的三个覆盖面板

<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

【问题讨论】:

  • 看看更新formDialogappendToBody="true",我认为这是解决问题的关键。
  • 我试图查看这个属性 appendToBody,但没有成功

标签: jsf primefaces


【解决方案1】:

我没有看到我在表单中使用它,请将元素放在表单中。 '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 已被移除。使用 appendTo="@(body)" 而是。

您可以查看更多信息here

【讨论】:

  • formDialog 是一个包含所有内容的表单,当单击该面板中的任何按钮并发出请求时,所有内容都将被更新。但是,我也尝试按照您的方式进行操作,但没有成功
  • 用一个或几个项目测试它以排除可能的错误。在这里您可以看到使用叠加面板的示例:primefaces.org/showcase/ui/overlay/…
  • 我明白了,我从星期五开始就一直在做这个 sprint 活动,所以我最终尝试了几件事,包括这个以更多地隔离错误并只使用覆盖。例如,我看到同样的行为发生在我不仅单击按钮时,而且当我打开对话框本身时。每次我这样做,+三个overlayPanels被创建,而不是重复使用,好像组件处理是错误的,我不确定,但我继续在我的机器上进行测试。
  • 还请注意我在回答中添加的关于从 6.2 版到 7 版关于 appendToBody 的更改的最后一件事
  • 我明白了!现在这个属性的错误已经消失了,muito obrigado amigo!
猜你喜欢
  • 2014-03-15
  • 2021-08-11
  • 2011-10-24
  • 2016-12-21
  • 2016-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多