【问题标题】:JavaScript retrieves data before Primefaces AJAX event call has been finishedJavaScript 在 Primefaces AJAX 事件调用完成之前检索数据
【发布时间】:2012-02-02 05:56:18
【问题描述】:

在 TabView primefaces 组件中,在 tabChange 上,我想做一个 ajax 调用来更新 bean 中的 bean 数据,然后需要由 javascript 处理(一些图表)。

我遇到的问题是数据通过我的 ajax 调用正确更新,但使用数据的 javascript 在 ajax 调用更新之前被检索。

这是在 tabChange 事件上带有 ajax 调用的 primeface 组件。

<p:tabView>
        <p:ajax event="tabChange" listener="#{bean.onTabChange}" />
        <p:tab title="Tab 1" id="tab1">
                //chart1
        </p:tab>  

        <p:tab title="Tab 2" id="tab2">
               //chart2    
        </p:tab>  

        <p:tab title="Tab 3" id="tab3">
              //chart3
        </p:tab>  
</p:tabView> 

这是 JavaScript:

function renderTheChart(tabIndex) { 
    var categories= [];
    var categories= [];

    <ui:repeat var="data" value="#{bean.dataList}">
        categories[categories.length] = "#{data.id}";
        values[values.length] = #{data.value};
    </ui:repeat>


    renderChart(values, categories, tabIndex);          
}

要知道何时调用 javascript 来更新组件,我尝试了客户端回调。

<p:tabView onTabChange="handleTabChange(event, index)">

JavaScript:

function handleTabChange(event, index) {
     renderTheChart(index);
}

【问题讨论】:

    标签: java ajax jsf-2 primefaces


    【解决方案1】:

    如果您在&lt;p:tabView&gt; 组件的属性onTabChange 中指定您的JavaScript 函数,它将在您在&lt;p:ajax&gt; 组件中指定的事件之前触发。因此,您的 JavaScript 函数将在更新之前从服务器接收旧数据。

    PrimeFaces 的&lt;p:ajax&gt; 组件有一个属性oncomplete,这正是您应该设置JavaScript 函数的地方。应该是这样的:

    <p:ajax event="tabChange" listener="#{bean.onTabChange}" 
            oncomplete="handleTabChange(event, index);" update="someIDs"/>
    

    您的 JavaScript 函数现在只会在您的 bean.onTabChange 函数返回时触发。此外,不要忘记使用&lt;p:ajax&gt;update 属性重新渲染页面中应该显示新数据的任何部分。

    【讨论】:

    • 这是更好的答案。我忘了 &lt;p:ajax&gt; 已经有 oncomplete 属性了。
    • 我没有看到这个更新,直到我尝试了 maples 解决方案并且它起作用了。然而,这确实看起来像枫树所说的那样,更整洁。我试过了,但我收到一条错误消息,提示“未定义索引”。然而,它确实只发送“事件”。是否可以从事件对象中检索索引(或选项卡 ID?)?
    • hmm...我认为您可能需要将index 存储在一些隐藏的输入中并更新该输入onTabChange。否则,客户端的浏览器永远无法获得您在服务器端持有的值。
    【解决方案2】:

    发生的情况是onTabChange Javascript 在服务器回发发生之前执行。这是正常行为,虽然许多 Primefaces 组件都有 oncomplete 属性,但 TabView 没有这样的属性。

    您可以告诉 Javascript 在回发返回时执行的一种方法是在 RequestContext 上添加一个 javascript。在动作侦听器方法onTabChange 中添加以下代码会将脚本添加到回发中。

    RequestContext context = RequestContext.getCurrentInstance();
    context.execute("renderTheChart(" + tabIndex + ");");
    

    您可能会遇到的另一个问题是,如果您没有在表单中指定要从&lt;p:ajax&gt; 组件更新的元素,那么&lt;ui:repeat&gt; 标记可能不会被#{bean.dataList} 的新值刷新。您可以使用 ajax 组件的 update 属性指定更新表单元素,也可以将其添加到操作侦听器中的 RequestContext 中。

    //update panel   
    context.addPartialUpdateTarget("form:panel");
    

    【讨论】:

    • 一切正常!感谢 的提示。它确实引起了问题,但正如您所提到的,通过在 ajax 组件中添加“更新”来解决!谢谢!
    • @user373455 没问题 :) 如果您查看下面 Mr.J4mes 的答案,它也应该解决 Javascript 的问题,在我看来这是一个更清洁的解决方案,因为它不需要额外的 Java 代码.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-17
    • 2014-07-06
    • 2018-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多