javascript p:commandButton onclick 中的 EL 表达式不会在 ajax 请求上更新/重新呈现?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8822484/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 04:41:29  来源:igfitidea点击:

EL expression inside p:commandButton onclick does not update/re-render on ajax request?

javascriptjsfprimefacesel

提问by Murat Derya ?zen

The onclickattribute of my commandButtonhas some EL dependent Javascript inside. To be more specific, here is that piece of code:

onclickmy的属性commandButton里面有一些依赖于 EL 的 Javascript。更具体地说,这是一段代码:

<p:commandButton
    onclick="javascript: if('#{userBean.user.friendList.size() gt 0}' == 'true') deleteFriendsConfirmDialog.show(); else friendsAlreadyDeletedErrorDialog.show();"
    value="Delete all friends?" />

deleteFriendsConfirmDialogclears the list of friends and updates the @form. The list of friends, commandButton and the dialogs are all in that form.

deleteFriendsConfirmDialog清除好友列表并更新@form. 好友列表、commandButton 和对话框都采用这种形式。

So I click the button, confirmation dialog comes up (because the length of friends' list is gt 0), I confirm and the list is emptied, the view is updated. However, when I click the Delete all friends?button once more, the confirmation dialog comes up again. Since the length of the list is now 0, I instead expect the error dialog to show.

所以我点击按钮,确认对话框出现(因为朋友列表的长度是 gt 0),我确认并清空列表,更新视图。但是,当我Delete all friends?再次单击该按钮时,再次出现确认对话框。由于列表的长度现在为 0,我希望显示错误对话框。

That, I guess, is because the Javascript written inside onclickis not updated (although the button is in the form).

那,我猜,是因为里面写的Javascriptonclick没有更新(虽然按钮在表单中)。

Edit:Changing #{userBean.user.friendList.size() gt 0}to #{not empty userBean.user.friendList}doesn't work neither.

编辑:更改#{userBean.user.friendList.size() gt 0}#{not empty userBean.user.friendList}也不起作用。

How come? What's wrong here?

怎么来的?这里有什么问题?

Any help appreciated. :)

任何帮助表示赞赏。:)

回答by BalusC

Indeed. PrimeFaces (and standard JSF) does not re-evaluate the EL in on*attributes on a per-request basis. It only happens on a per-view basis. RichFaces however does that in <a4j:xxx>components.

的确。PrimeFaces(和标准 JSF)不会on*在每个请求的基础上重新评估属性中的 EL 。它只发生在每个视图的基础上。然而,RichFaces 在<a4j:xxx>组件中做到了这一点。

You need to solve the problem differently. I suggest to use the visibleattribute of the <p:dialog>instead.

您需要以不同的方式解决问题。我建议改用 the 的visible属性<p:dialog>

<h:form>
    ...
    <p:commandButton value="Delete all friends?" update=":deleteDialogs" />
</h:form>
...
<h:panelGroup id="deleteDialogs">
    <p:dialog id="deleteFriendsConfirmDialog" visible="#{facesContext.postback and not empty userBean.user.friendList}">
        ...
    </p:dialog>
    <p:dialog id="friendsAlreadyDeletedErrorDialog" visible="#{facesContext.postback and empty userBean.user.friendList}">
        ...
    </p:dialog>
</h:panelGroup>

An alternative is to use PrimeFaces' RequestContextin the bean's action method which allows you to execute JavaScript code programmatically in bean's action method (although this tight-couples the controller a bit too much with the view, IMO).

另一种方法是RequestContext在 bean 的 action 方法中使用 PrimeFaces' ,它允许您在 bean 的 action 方法中以编程方式执行 JavaScript 代码(尽管这将控制器与视图紧密耦合,IMO)。

<p:commandButton value="Delete all friends?" action="#{userBean.deleteAllFriends}" />

with

RequestContext context = RequestContext.getCurrentInstance();

if (!user.getFriendList().isEmpty()) {
    context.execute("deleteFriendsConfirmDialog.show()");
} else {
    context.execute("friendsAlreadyDeletedErrorDialog.show()");
}


Unrelatedto the concrete problem, your original onclick, while it does not work out in your particular case, shows some poor practices. The javascript:pseudoprotocol is superfluous. It's the default already. Remove it. Also the test against == 'true'is superfluous. Remove it. Just let the EL print trueor falsedirectly. The following is the proper syntax (again, this does not solve your problem, just for your information)

具体问题无关,您的原始onclick,虽然它在您的特定情况下不起作用,但显示了一些不良做法。该javascript:pseudoprotocol是多余的。已经是默认了。去掉它。此外,针对的测试== 'true'也是多余的。去掉它。只是让EL打印truefalse直接。以下是正确的语法(同样,这不能解决您的问题,仅供参考)

<p:commandButton
    onclick="if (#{not empty userBean.user.friendList}) deleteFriendsConfirmDialog.show(); else friendsAlreadyDeletedErrorDialog.show();"
    value="Delete all friends?" />

It would have worked if you were using RichFaces' <a4j:commandButton>.

如果您使用 RichFaces' ,它会起作用<a4j:commandButton>

<a4j:commandButton
    oncomplete="if (#{not empty userBean.user.friendList}) deleteFriendsConfirmDialog.show(); else friendsAlreadyDeletedErrorDialog.show();"
    value="Delete all friends?" />