Primefaces AJAX update =“@ form”两次调用监听器

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Primefaces AJAX update =“@ form”两次调用监听器相关的知识,希望对你有一定的参考价值。

我有一个页面顶部有一些选项,当更改时更新同一页面上的某些图表。以下是相关过滤器部分:

<p:fieldset id="filtrosDashboard" legend="Filtros" toggleable="true" toggleSpeed="500" collapsed="#{beanJanela.filtroCollapsed}">

<!--Site filter-->
<div class="ui-g-12 ui-md-12 ui-lg-8">
    <p:outputLabel for="ObrasPickList" value="#{beanJanela.tituloLabelSelecaoObrasFiltro}" styleClass="tituloFiltro"/>
    <p:pickList id="ObrasPickList" value="#{beanJanela.obras}" var="obra" effect="slide"
                itemValue="#{obra}" itemLabel="#{obra.descricao}"
                showSourceFilter="true" showTargetFilter="true" showCheckbox="true"
                filterMatchMode="contains" converter="obraConverter" responsive="true"
                addLabel="Adicionar" addAllLabel="Adicionar tudo" 
                removeLabel="Remover" removeAllLabel="Remover tudo"
                rendered="#{beanJanela.showMultiplasObrasFiltro}">

        <f:facet name="sourceCaption">Obras</f:facet>
        <f:facet name="targetCaption">Selecionadas</f:facet>

        <p:ajax event="transfer" listener="#{beanJanela.atualizaGraficos}" update="@form"/>

        <p:column style="width: 92%">
            <h:outputText value="#{obra.descricao}" />
        </p:column>
    </p:pickList>
</div>

<!--Date filter-->
<div class="ui-g-12 ui-md-12 ui-lg-4">
    <p:outputLabel for="periodo" value="Período" styleClass="tituloFiltro" rendered="#{beanJanela.showPeriodoFiltro}"/>
    <div class="ui-inputgroup">
        <p:inputText id="periodo" value="#{beanJanela.periodo}" rendered="#{beanJanela.showPeriodoFiltro}">
            <p:ajax event="change" listener="#{beanJanela.atualizaGraficos}" update="@form"/>
        </p:inputText>
        <span class="ui-inputgroup-addon"><i class="fa fa-fw fa-calendar"></i></span>
    </div>
</div>

</p:fieldset>

如您所见,有两个过滤器,一个是带有工作站点的pickList,另一个是使用名为daterangepicker的javascript库转换为数据范围选择器的inputText

我为<p:ajax/>定义了一个transfer事件pickList<p:ajax/>事件change另一个inputText,两者都调用相同的监听器#{beanJanela.atualizaGraficos}并且它们都更新包含过滤器和图形的形式。

问题是如下,当我使用pickList它按预期工作时,方法atualizaGraficos只在辅助bean上调用一次;但是,如果我尝试使用日期过滤器进行过滤,则会调用atualizaGraficos方法两次。

为什么会这样?我已经看到一些与此问题类似的其他帖子,但在我的情况下,我有两个ajax调用,在同一个表单内的两个不同组件上有两个不同的事件。

以下是需要时的完整页面代码:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:p="http://primefaces.org/ui"
      xmlns:po="http://primefaces.org/omega">

    <h:head>
        <f:facet name="first">
            <meta http-equiv="X-UA-Compatible" content="IE=edge" />
            <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
            <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>
            <meta name="apple-mobile-web-app-capable" content="yes" />
            <meta http-equiv="refresh" content="#{session.maxInactiveInterval};url=#{request.contextPath}/index.xhtml"/>
            <title>Evop</title>
        </f:facet>

        <link rel="shortcut icon" type="image/png" href="/evop/resources/imagem/icone_evop.png"/>

        <script type="text/javascript">
            $(document).ready(function () {
                $("form").bind("keypress", function (e) {
                    if (e.keyCode === 13) {
                        return false;
                    }
                });
            });

            $(document).ready(function () {
                $(window).keydown(function (event) {
                    if (event.keyCode === 13) {
                        return false;
                    }
                });
            });
        </script>

        <h:outputScript name="js/nanoscroller.js" library="resources" />
        <h:outputScript name="js/layout.js" library="resources" />
        <h:outputScript name="js/script.js" library="resources" />
        <h:outputScript name="js/all.js" library="font-awesome" />

        <h:outputStylesheet name="css/layout.css" library="resources" />
        <h:outputStylesheet name="css/primeflex.css" library="resources" />
        <h:outputStylesheet name="css/animate.css" library="resources" />
        <h:outputStylesheet name="css/nanoscroller.css" library="resources" />
        <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/daterangepicker/daterangepicker.css" />
        <h:outputStylesheet name="css/all.css" library="font-awesome"/>
        <h:outputStylesheet name="css/styleCadastro.css" library="resources"/>
        <h:outputStylesheet name="css/styleDashboards.css" library="resources"/>

        <ui:insert name="head"/>
    </h:head>

    <h:body styleClass="main-body">
        <div class="wrapper">
            <div class="topbar clearfix">
                <a id="omega-menu-button" href="#">
                    <span class="fa fa-bars"></span>
                </a>

                <span class="topbar-title">Dashboard</span>
            </div>

            <h:form id="menuform">
                <div class="sidebar">
                    <div class="nano">
                        <div class="nano-content sidebar-scroll-content menu-flex">

                            <!--MENU-->

                        </div>
                    </div>
                </div>
            </h:form>

            <div class="main">
                <ui:param name="beanJanela" value="#{comprasDashboardsBean}" />

                <h:form id="dashboardCompras" prependId="false">
                    <p:growl id="growl" showDetail="true" showSummary="true" sticky="false" escape="false"><p:autoUpdate/></p:growl>

                    <div style="margin-top: 15px;">
                        <div class="ui-g ui-g-fluid dashboard">

                            <!--Filterns-->
                            <div class="ui-g-12 filtro_obras filtro_obras2">      
                                <div class="filtro_card clearfix chatSummary">
                                    <p:fieldset id="filtrosDashboard" legend="Filtros" toggleable="true" toggleSpeed="500" collapsed="#{beanJanela.filtroCollapsed}">

                                        <!--Site filter-->
                                        <div class="ui-g-12 ui-md-12 ui-lg-8">
                                            <p:outputLabel for="ObrasPickList" value="#{beanJanela.tituloLabelSelecaoObrasFiltro}" styleClass="tituloFiltro"/>
                                            <p:pickList id="ObrasPickList" value="#{beanJanela.obras}" var="obra" effect="slide"
                                                        itemValue="#{obra}" itemLabel="#{obra.descricao}"
                                                        showSourceFilter="true" showTargetFilter="true" showCheckbox="true"
                                                        filterMatchMode="contains" converter="obraConverter" responsive="true"
                                                        addLabel="Adicionar" addAllLabel="Adicionar tudo" 
                                                        removeLabel="Remover" removeAllLabel="Remover tudo"
                                                        rendered="#{beanJanela.showMultiplasObrasFiltro}">

                                                <f:facet name="sourceCaption">Obras</f:facet>
                                                <f:facet name="targetCaption">Selecionadas</f:facet>

                                                <p:ajax event="transfer" listener="#{beanJanela.atualizaGraficos}" update="@form"/>

                                                <p:column style="width: 92%">
                                                    <h:outputText value="#{obra.descricao}" />
                                                </p:column>
                                            </p:pickList>
                                        </div>

                                        <!--Date filter-->
                                        <div class="ui-g-12 ui-md-12 ui-lg-4">
                                            <p:outputLabel for="periodo" value="Período" styleClass="tituloFiltro" rendered="#{beanJanela.showPeriodoFiltro}"/>
                                            <div class="ui-inputgroup">
                                                <p:inputText id="periodo" value="#{beanJanela.periodo}" rendered="#{beanJanela.showPeriodoFiltro}">
                                                    <p:ajax event="change" listener="#{beanJanela.atualizaGraficos}" update="@form"/>
                                                </p:inputText>
                                                <span class="ui-inputgroup-addon"><i class="fa fa-fw fa-calendar"></i></span>
                                            </div>
                                        </div>

                                    </p:fieldset>
                                </div>
                            </div>
                            <!--End of filters-->

                            <!-- SOME GRAPHS THAT ARE UPDATED WHEN THE FILTER CHANGES -->

                            <!-- SCRIPTS FOR THE DATE FILTER -->
                            <script type="text/javascript" src="https://cdn.jsdelivr.net/momentjs/latest/moment.min.js"></script>
                            <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/daterangepicker/daterangepicker.min.js"></script>
                            <h:outputScript name="js/dashboardExtender.js" library="resources" />
                            <script>
                                $(document).ready(function () {
                                    var start = moment().subtract(29, 'days');
                                    var end = moment();

                                    function cb(start, end) {
                                        $('#periodo').text(start.format('L') + ' - ' + end.format('L'));
                                    }

                                    $("#periodo").daterangepicker({
                                        startDate: start,
                                        endDate: end,
                                        "locale": {
                                            "format": "DD/MM/YYYY",
                                            "separator": " - ",
                                            "applyLabel": "Salvar",
                                            "cancelLabel": "Cancelar",
                                            "fromLabel": "De",
                                            "toLabel": "Para",
                                            "customRangeLabel": "Definir Período",
                                            "weekLabel": "S",
                                            "daysOfWeek": [
                                                "Dom",
                                                "Seg",
                                                "Ter",
                                                "Qua",
                                                "Qui",
                                                "Sex",


                                 "Sab"
                                        ],
                                        "monthNames": [
                                            "Janeiro",
                                            "Fevereiro",
                                            "Março",
                                            "Abril",
                                            "Maio",
                                            "Junho",
                                            "Julho",
                                            "Agosto",
                                            "Setembro",
                                            "Outubro",
                                            "Novembro",
                                            "Dezembro"
                                        ],
                                        "firstDay": 1
                                    },
                                    ranges: {
                                        'Últimos 7 Dias': [moment().subtract(6, 'days'), moment()],
                                        'Últimos 15 Dias': [moment().subtract(14, 'days'), moment()],
                                        'Últimos 30 Dias': [moment().subtract(29, 'days'), moment()],
                                        'Esse Mês': [moment().startOf('month'), moment().endOf('month')],
                                        'Último Mês': [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')]
                                    }
                                }, cb);

                                cb(start, end);
                            });
                        </script>

                    </div>
                </div>
            </h:form>
        </div>
    </div>

    <p:ajaxStatus onstart="PF('statusDialog').show();" oncomplete="PF('statusDialog').hide();">
        <p:dialog widgetVar="statusDialog"
                  modal="true"
                  draggable="false"
                  closable="false"
                  resizable="false"
                  showHeader="false"
                  style="margin: 0; padding: 0;">
            <p:graphicImage name="/imagem/ajax-loader.gif" />
        </p:dialog>
    </p:ajaxStatus>
</h:body>

答案

我不知道为什么在第二个ajax调用上调用update="@form"两次触发atualizaGraficos方法,而在第一个ajax调用上同样的事情只触发了一次。

话虽这么说,我的问题的解决方案是定义我想要直接更新到第二个ajax调用的<p:ajax/>组件的更新标签的图表的ID。

如果您知道第一种方法为什么两次更新表单,请告诉我。

以上是关于Primefaces AJAX update =“@ form”两次调用监听器的主要内容,如果未能解决你的问题,请参考以下文章

JSF + PrimeFaces:`update` 属性不更新组件

PrimeFaces Datatable单击分页链接取消选中所有复选框

update="@(.myClass)" 中的 PrimeFaces 选择器如何工作?

使用ajax从jsf中的primefaces树选定项设置primefaces selectOneMenu默认值

Primefaces选项卡ajax部分更新错误

JSF(Primefaces)通过ID更新几个元素的ajax