javascript 中修改的值未在 JSF PhaseListener 中更新

values modified in javascript not getting updated in JSF PhaseListener

最初hold_mode值设置为0,点击commandButton后,通过JavaScriptonclick事件变为1...但是在PhaseListener beforePhase()方法,值为0。我不明白为什么这个值仍然是 0

任何人都可以解释一下吗?

info.xhtml

<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}"/>

JavaScript

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;
    }
}

PhaseListener

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 时,出现以下异常
java.lang.IllegalStateException: FacesContext already released

修改后问题得到解决PhaseListener

  1. 为什么我得到 IllegalStateException 是因为我在全局声明了 FacesContext 对象 old。在那种情况下,我在 befoerPhase 方法中声明了它,因为我们没有在全局范围内声明 FacesContext..

  2. 在代码修改之前,我们所做的是删除 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) {
    
        }
    

    }