JSF 1.2 Life Cycle understanding: Executing the ValueChangeListener method in InvokeApplication phase

倾然丶 夕夏残阳落幕 提交于 2020-01-14 06:26:22

问题


I am using a <h:selectBooleanCheckbox> in the facet header of a DataTable. All the rows content for that <h:column> DataTable are <h:selectBooleanCheckbox>. The rows are getting selected perfectly the way I wanted. Below is the code I used:

<h:form>
<h:dataTable
    value="#{employeeService.employeeList }"
    var="empl"
    binding="#{employeeService.dataTablebinding }">
    ......
    ......
    ......
    <h:column>
            <f:facet name="header">             
                <h:selectBooleanCheckbox id="chkBoxAll" value="#{employeeService.checkedHdr }" valueChangeListener="#{employeeService.checkAll }" onclick="submit()"></h:selectBooleanCheckbox>
            </f:facet>
            <h:selectBooleanCheckbox id="tableChkBox" value="#{empl.checked }" valueChangeListener="#{employeeService.getCheckChanged }" onclick="submit()"></h:selectBooleanCheckbox>
        </h:column>
</h:dataTable>

This is the code for the ValueChangeListener:

public void checkAll(ValueChangeEvent event){
    if(isInvokeApplicationPhase(event)){
        Iterator<Employee> empl = employeeList.iterator();
        while(empl.hasNext()){
            Employee emp = empl.next();             
            emp.setChecked(checkedHdr);
        }
    }
}

This is the isInvokeApplicationPhase utility I added up for making this code work (referred the solution suggested by BalusC in this link: JSF 1.2: valueChangeListener event not returning newly selected value ):

public boolean isInvokeApplicationPhase(FacesEvent event){      
    if(event.getPhaseId() != PhaseId.INVOKE_APPLICATION){
        event.setPhaseId(PhaseId.INVOKE_APPLICATION);
        event.queue();
        return false;
    }       
    return true;
}

Now my Question:

What is the use of that isInvokeApplicationPhase check in the ValueChangeListener method? If I comment out this check then it does not work - WHY? I thought I have understood the JSF life cycle properly but this behavior proves that I have not :(

Kindly let me know the explanation based on the JSF life cycle phases.


回答1:


The value change listener runs during validations phase and is intented to hook on the value change event. I.e. the newly submitted value is different from the original model value.

The validations phase runs before update model values phase, wherein JSF set all submitted, converted and validated values in the model (the backing bean's properties). So when you attempt to change the model value of a different field in the value change listener, then it would be overridden during the update model values phase.

This particular trick re-queues the value change event to the invoke application phase, which runs after update model values phase. So when you attempt to change the model value of a different field, then it won't be overriden.

In a nutshell: the validations phase is simply the wrong moment to manually manipulate the model values and the invoke application phase is the right moment to manually manipulate the model values.

Actually, the value change event is being abused here. You should rather be using an action event here, but this was not available for inputs in JSF 1.x. This was only available in JSF 2.x in flavor of <f:ajax listener>.

See also:

  • When to use valueChangeListener or f:ajax listener?
  • Setter not called for input text


来源:https://stackoverflow.com/questions/16261687/jsf-1-2-life-cycle-understanding-executing-the-valuechangelistener-method-in-in

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!