最初hold_mode
值设置为0
,在commandButton
点击后,它通过JavaScript onclick事件更改为1 ...但在PhaseListener beforePhase()方法中,值为{ {1}}。我不明白为什么价值仍为0
。
谁能请你解释一下这个问题。?
0
<h:form id="userForm">
<h:inputHidden id="hold_mode" value="0" />
<h:commandButton id="hold" style="width: 60px;" value="#{myForm.holdbtntitle}" disabled="#{myForm.holdbtn}" action="#{myForm.hold}" actionListener="#{convo.holdListener}" onclick="return send(true,'3');" rendered="#{myForm.holdpanelflg}"/>
function send(confirmFlg,msgFlg) {
isClicked = true;
if(confirmFlg) {
msg = 'From Hold';
if(confirm(msg) == false) {
isClicked = false;
event.returnValue = false;
return false;
}
}
if(isClicked) {
if(msgFlg == '3') {
document.all.item('myForm:hold_mode').value='1';
}
pep_OpenWaitDirect('../../../html/common/printwait.xhtml');
return true;
} else {
return false;
}
}
我试过这个public class RemoveValidateListener implements PhaseListener {
private static final long serialVersionUID = 3556867423746720962L;
private FacesContext old = null;
public void beforePhase(PhaseEvent e) {
System.out.println("Before "+e.getPhaseId());
if(e.getPhaseId().equals(PhaseId.PROCESS_VALIDATIONS)) {
UIComponent comp = FacesContext.getCurrentInstance().getViewRoot();
if(findHoldMode(comp)){
old = FacesContext.getCurrentInstance();
removeValidatorsForComponentTree(comp);
}
}
}
public void afterPhase(PhaseEvent e) {
System.out.println("After "+e.getPhaseId());
if(e.getPhaseId().equals(PhaseId.PROCESS_VALIDATIONS)) {
FacesContext context = FacesContext.getCurrentInstance();
UIComponent comp = FacesContext.getCurrentInstance().getViewRoot();
if(findHoldMode(comp)){
StateManager stateManager = (StateManager)context.getApplication().getStateManager();
stateManager.restoreView(old,old.getViewRoot().getViewId(),old.getViewRoot().getRenderKitId());
}
}
}
private boolean findHoldMode(UIComponent comp){
boolean rtnFlg = false;
List list = comp.getChildren();
for (int i = 0; i < list.size(); i++) {
UIComponent temp = (UIComponent) list.get(i);
if (!(temp instanceof HtmlBody)) {
continue;
} else {
List<UIComponent> childList = temp.getChildren();
for (int j = 0; j < childList.size(); j++) {
UIComponent childTemp = (UIComponent) childList.get(j);
if (!(childTemp instanceof HtmlPanelGrid)) {
continue;
} else {
List<UIComponent> child2List = childTemp.getChildren();
for (int k = 0; k < child2List.size(); k++) {
UIComponent child2Temp = (UIComponent) child2List.get(k);
if (!(child2Temp instanceof HtmlForm)) {
continue;
}
UIComponent hold = child2Temp.findComponent(JsfBase.HOLD_MODE_COMPNAME);
if (hold == null) {
continue;
}
if (!(hold instanceof UIInput)) {
continue;
}
Object mode = ((UIInput) hold).getValue();
if (mode == null || !(mode.toString().equals(JsfBase.HOLD_MODE_ON))) {
continue;
} else {
rtnFlg = true;
((UIInput) hold).setValue("0");
break;
}
}
}
}
}
}
return rtnFlg;
}
private void removeValidatorsForComponentTree(UIComponent comp){
removeValidators(comp);
List complist = comp.getChildren();
if (complist.size()>0){
for(int i = 0; i < complist.size(); i++) {
UIComponent uicom = (UIComponent) complist.get(i);
removeValidatorsForComponentTree(uicom);
}
}
}
private void removeValidators(UIComponent comp){
if(comp instanceof UIInput){
removeValidator((UIInput)comp);
}
}
public void removeValidator(UIInput comp){
Validator[] validator = comp.getValidators();
for(int i=0;i < validator.length;i++){
comp.removeValidator(validator[i]);
}
if(comp.isRequired()){
comp.setRequired(false);
}
}
}
并且它适用于当前屏幕,但问题是当我点击其他屏幕中的<h:inputHidden id="hold_mode" value="0" immediate="true" />
时,出现以下异常
commandButton
答案 0 :(得分:1)
修改后的PhaseListener
为什么我得到IllegalStateException
,因为我已全局声明FacesContext
对象old
。在那种情况下,我在befoerPhase
方法中声明了它,因为我们没有在全球范围内声明FacesContext
..
在修改代码之前,我们所做的是删除了beforePhase
中的验证程序,我们正在afterPhase
恢复视图状态,但它无法正常工作。所以我现在在beforePhase
中删除验证器之前保存视图状态,而不是在afterPhase
中恢复它。
public class RemoveValidateListener implements PhaseListener {
private static final long serialVersionUID = 3556867423746720962L;
public void beforePhase(PhaseEvent e) {
if (e.getPhaseId().equals(PhaseId.PROCESS_VALIDATIONS)) {
FacesContext context = FacesContext.getCurrentInstance();
UIComponent comp = context.getViewRoot();
StateManager stateManager = (StateManager) context.getApplication().getStateManager();
stateManager.saveView(context);
if (findHoryuMode(comp)) {
removeValidatorsForComponentTree(comp);
}
}
}
public void afterPhase(PhaseEvent e) {
}
}