问题
The onclick
attribute of my commandButton
has some EL dependent Javascript inside. To be more specific, here is that piece of code:
<p:commandButton
onclick="javascript: if('#{userBean.user.friendList.size() gt 0}' == 'true') deleteFriendsConfirmDialog.show(); else friendsAlreadyDeletedErrorDialog.show();"
value="Delete all friends?" />
deleteFriendsConfirmDialog
clears the list of friends and updates the @form
. The list of friends, commandButton and the dialogs are all in that form.
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.
That, I guess, is because the Javascript written inside onclick
is not updated (although the button is in the form).
Edit: Changing #{userBean.user.friendList.size() gt 0}
to #{not empty userBean.user.friendList}
doesn't work neither.
How come? What's wrong here?
Any help appreciated. :)
回答1:
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.
You need to solve the problem differently. I suggest to use the visible
attribute of the <p:dialog>
instead.
<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' RequestContext
in 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).
<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()");
}
Unrelated to 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 true
or false
directly. The following is the proper syntax (again, this does not solve your problem, just for your information)
<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>
.
<a4j:commandButton
oncomplete="if (#{not empty userBean.user.friendList}) deleteFriendsConfirmDialog.show(); else friendsAlreadyDeletedErrorDialog.show();"
value="Delete all friends?" />
来源:https://stackoverflow.com/questions/8822484/el-expression-inside-pcommandbutton-onclick-does-not-update-re-render-on-ajax-r