如何从primefaces中的javascript触发组件刷新?

Posted

技术标签:

【中文标题】如何从primefaces中的javascript触发组件刷新?【英文标题】:How to trigger component refresh from javascript in primefaces? 【发布时间】:2012-05-24 20:37:21 【问题描述】:

是否可以从 javascript 更新 PrimeFaces 组件以便强制刷新?

我正在使用对话框中的此按钮进行 ajax 保存调用。 我已在 oncomplete 事件上附加了我的自定义 javascript。

<p:growl life="1500" id="showmessage"/>
<p:dialog id="addMemberDialog" widgetVar="addMemberDlg">
    <!-- More Code -->
    <p:commandButton value="Save"
        actionListener="#memberManagedBean.save"
        oncomplete="handleSaveNewMember(xhr, status, args)"
        update=":memberListForm:membersTable createupdateform "
        process="@form" />
</p:dialog>

..在保存按钮期间,我在此处添加一条消息以使用咆哮组件将其显示给客户端。

public void save(ActionEvent event) 
    FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO,
            "Successfuly Add user", "Successfuly Add user");
    FacesContext.getCurrentInstance().addMessage(null, message);


我的问题是,如何对 UI 进行排序,以便在咆哮组件显示消息之前先隐藏对话框?

function handleSaveNewMember(xhr, status, args) 
    addMemberDlg.hide();
    //update the growl after the dialog was hidden?

发生的事情是咆哮组件同时显示在对话框旁边。

谢谢。

【问题讨论】:

您必须在单击按钮时显示对话框。您是否尝试从该按钮而不是对话框中的“保存”按钮更新咆哮? 【参考方案1】:

您可以为此使用 PrimeFaces 的 &lt;p:remoteCommand&gt;

<p:remoteCommand name="updateGrowl" update="showmessage" />

将被调用为

<p:commandButton ... oncomplete="addMemberDlg.hide(); updateGrowl();" />

这种特殊情况中,有一种更简单的方法。将&lt;p:growl&gt;autoUpdate属性设置为true

<p:growl autoUpdate="true" life="1500" id="showmessage"/>

它会在每次 ajax 请求时自动更新。如果您的组件实际上不支持它,那么您始终可以将其包装在同样支持该属性的 &lt;p:outputPanel&gt; 中。

<p:outputPanel autoUpdate="true">
    ...
</p:outputPanel>

【讨论】:

仅供参考,如果读者使用的是侏罗纪版本的 PF,则仅 3.0 及更高版本才可使用咆哮的自动更新。 blog.primefaces.org/?p=1164 并且 autoUpdate="..." 属性在 6.2 精英版本中被弃用,取而代之的是 &lt;p:autoUpdate&gt; 标签/元素,这也将出现在下一个社区版本中。 github.com/primefaces/primefaces/wiki/Migration-Guide【参考方案2】:

你总是可以做这样的事情(从你的保存按钮更新属性中删除 showmessage id)

<h:commandButton style="display:none" id="myBtn" >
    <f:ajax render=":showmessage"/>
</h:commandButton>

function handleSaveNewMember(xhr, status, args) 
    ...
    jQuery("#myBtn").click();

编辑 但无论如何,在您当前的代码中,对话框不是在更新 grwol 的同时关闭吗?

【讨论】:

你的意思是需要一个“虚拟”按钮,而这不能通过一些 javascript api 完成吗?如果是这种情况,我想知道我应该点击这个链接forum.primefaces.org/…。由于一切都被 ajaxified 那么我应该从客户端本身触发消息。我的理解正确吗? 但在您的情况下,您想从服务器发送消息,而不是从 js...关于我的方法...我想还有其他方法...但这就是我触发“重新渲染”的方式来自 js 的 jsf 元素:) 哦,你是对的。我已经从更新列表中删除了显示消息,因为这会自动显示面部消息。让我尝试进一步解释一下,单击保存按钮时,我已将面部消息排队。由于咆哮的自​​动更新是错误的,因此消息不会显示。这就是 oncomplete javascript 函数的目的。发生的情况是我会首先隐藏对话框,然后我希望咆哮声刷新并显示我排队的消息。这可能吗? 我认为 atm 的唯一方法是我提议的方式...但是无论如何在您当前的代码中,对话框不是在更新 grwol 的同时关闭吗?【参考方案3】:

我的建议:

    &lt;p:remoteCommand&gt;actionListener 属性一起使用。此属性调用包含 FacesContext.addMessage 代码的支持 bean 方法,这样:&lt;p:remoteCommand actionListener="myBean.testMethod()" /&gt; 接下来,在您的handleSaveNewMember 脚本中,在addMemberDlg.hide(); 之后调用remoteCommand name 属性:&lt;p:remoteCommand name="testScript" actionListener="myBean.testMethod()"/&gt;。然后,function handleSaveNewMember(xhr, status, args) addMemberDlg.hide(); testScript(); update属性添加到remoteCommand指向咆哮组件:&lt;p:remoteCommand name="testScript" actionListener="myBean.testMethod()" update="showmessage" /&gt; 您的commandButton 没问题。

这对我有用。

您好。

【讨论】:

【参考方案4】:

为什么不能将 p:Dialog 放在 中。喜欢

< h:panelGroup id="addUser" rendered = "boolean value " >
    < p:dialog id="addMemberDialog" widgetVar="addMemberDlg" >
        <!-- More Code -->
        < p:commandButton value="Save" actionListener="#memberManagedBean.createOrUpdate"
                oncomplete="handleSaveNewMember(xhr, status, args)"
                update=":memberListForm:membersTable createupdateform :showmessage :addUser"
                process="@form" />
    < /p:dialog >
< /h:panelGroup>

应该在你的保存方法中设置的布尔值。在您的保存方法中将其设置为 false 时,它​​在更新时不会显示。所以只会显示咆哮消息。但在调用此保存方法之前,此布尔值设置为 true。

【讨论】:

【参考方案5】:

您可以使用名为 p:remotecommand 的 PrimeFaces 元素。该元素将执行一个动作(例如调用 bean 方法)并在该动作之后执行更新。

这篇文章中有一个例子http://devdublog.blogspot.com/2015/04/best-way-for-calling-method-of.html

【讨论】:

答案通常应该包含一些上下文,而不仅仅是一个链接。这将更适合作为对该问题的评论。见:meta.stackexchange.com/questions/8231/… 感谢您的建议。我已编辑评论以实现此功能。【参考方案6】:

PrimeFaces 有一个Ajax API。您可以使用PrimeFaces.ajax.Request.handle(cfg) 或更短的版本PrimeFaces.ab(cfg) 通过使用配置对象的update 属性来触发更新。

您可能希望根据需要设置process 属性。如果您不需要处理任何内容,请将其设置为 @none

然后,您需要设置source 属性。您可以使用 EL 将其设置为当前组件:#component.clientId

把这些放在一起,你会得到:

PrimeFaces.ab(source:'#component.clientId',process:'@none',update:'clientIdToUpdate')

我创建了一个custom EL function 以将其减少为#my:ajaxUpdate('clientIdToUpdate')

public static String ajaxUpdate(final String clientIds) 
  return "PrimeFaces.ab(source:'"
                 + UIComponent.getCurrentComponent(Faces.getContext()).getClientId()
                 + "',process:'@none',update:'"
                 + clientIds
                 + "')";

这减少了(例如):

<p:remoteCommand name="updateMyComponent" update="myComponent"/>
...
<p:ajax event="filter" oncomplete="updateMyComponent()"/>

到:

<p:ajax event="filter" oncomplete="#my:ajaxUpdate('myComponent')"/>

【讨论】:

以上是关于如何从primefaces中的javascript触发组件刷新?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 PrimeFaces 数据表自定义分页器

如何将JavaScript侦听器添加到PrimeFaces Ajax事件

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

PrimeFaces 数据表中的屏蔽数字

Primefaces:如何在 primefaces 3.5 中为菜单栏设置粘性

如何验证 primefaces 日期