本案的要求如下:
重复密码输入组件没有验证。
仅在对话框打开时验证密码输入组件。
为了满足#4我决定只在对话框打开时才渲染密码;否则不会呈现。
<p:commandButton
id="changePasswordButton"
value="Change Password"
actionListener="#{changePasswordBean.renderNewPasswordComponent()}"
update="newPassword"
oncomplete="PF('changePasswordDialog').show();"/>
<p:dialog id="changePasswordDialogId" widgetVar="changePasswordDialog">
<p:password
id="newPassword"
value="#{changePasswordBean.newPassword}"
rendered="#{changePasswordBean.getRenderNewPasswordComponent()}"
match="repeatPassword">
<f:validator validatorId="foo.bar.PasswordValidator"/>
</p:password>
<p:password id="repeatPassword"/>
<p:commandButton
value="Submit"
immediate="false"
validateClient="true"
process="@this newPassword repeatPassword"
actionListener="#{changePasswordBean.hideNewPasswordComponent()}"
update="newPassword repeatPassword"
oncomplete="if(!args.validationFailed) { PF('changePasswordDialog').hide(); }"/>
<p:commandButton type="reset" value="Reset"/>
<p:commandButton
value="Cancel"
immediate="true"
validateClient="false"
actionListener="#{changePasswordBean.hideNewPasswordComponent()}"
update="newPassword repeatPassword"
oncomplete="PF('changePasswordDialog').hide();"/>
</p:dialog>
支持Bean:
@ViewScoped
public class ChangePasswordBean {
private String newPassword;
private boolean renderNewPasswordComponent = false;
public boolean getRenderNewPasswordComponent() {
return renderNewPasswordComponent;
}
public void renderNewPasswordComponent() {
renderNewPasswordComponent = true;
}
public void hideNewPasswordComponent() {
renderNewPasswordComponent = false;
}
}
不幸的是它不起作用。对话框打开时,新密码字段无法正确呈现。
但是,如果我刷新浏览器窗口并再次单击“更改密码”按钮,则会正确呈现新密码字段。
如果单击“取消”或“提交”按钮,对话框将关闭。之后,如果我再次单击“更改密码”按钮,则会再次正确呈现新密码字段。这种情况无限制地来回传播,是理想的行为。
但是,如果单击“取消”或“提交”按钮(关闭对话框),请刷新浏览器窗口并单击“更改密码”按钮,新密码字段未正确呈现。
因此,似乎“更改密码”按钮,“提交”按钮和“取消”按钮不会更新新密码输入组件。阅读Execution order of events when pressing PrimeFaces p:commandButton后,看起来我已正确设置了所有内容。 actionListener在更新之前执行,在oncomplete之前执行。在ChangePasswordBean#renderNewPasswordComponent()
和ChangePasswordBean#hideNewPasswordComponent()
上设置断点表示正在执行动作侦听器。在ChangePasswordBean#getRenderNewPasswordComponent()
上设置断点表明密码组件正在检查是否应该呈现它。但是在触发actionListener之前和之后都会执行此方法。
单击“更改密码”按钮,这里是actionListener方法调用的顺序: