JSF 2.0 How to create state-saving UIComponents?
I tried simply:
public class UIDemoComponent extends UIComponentBase {
private String someVariable; // this gets always cleared, getters/setters omitted
public UIDemoComponent() {
super(); // place breakpoint here
}
@Override
public void encodeBegin(FacesContext context) throws IOException {
HtmlForm form = new HtmlForm();
form.setStyle("padding: 10px; b开发者_StackOverflow社区ackground-color: blue;");
getChildren().add(form);
AjaxBehavior behavior = new AjaxBehavior();
behavior.setRender(Arrays.asList("@form"));
form.addClientBehavior("click", behavior);
}
}
I have registered a tag handler and succesfully inserted the component into page. However, when I click the blue form that is rendered, JSF re-creates the component (breakpoint in the constructor is caught). The effect of this is that any instance variables are lost. How is one supposed to save data into components if they always get re-created?
I tried overriding and inspecting the state staving mechanisms of StateHolder
and PartialStateHolder
wihout luck:
@Override
public Object saveState(FacesContext context) {
return super.saveState(context); // breakpoint
}
@Override
public void restoreState(FacesContext context, Object state) {
super.restoreState(context, state); // breakpoint
}
JSF is executing the saveState
when page and components are created, but restoreState
is never called. Actually, when the AJAX request is being processed, a new instamnce of UIDemoComponent is created but saveState
method is called again, instead of restoreState
.
How to create such a state-saving component (that retains the instance fields over AJAX requests)?
Seems like JSF is running some pre-checks on state
object and not executing restoreState
at all if custom fields are not entered. Only after actually inserting custom values into state object, the restoreState
gets called.
For example:
@Override
public Object saveState(FacesContext context) {
Object[] rtrn = new Object[2];
rtrn[0] = super.saveState(context);
rtrn[1] = "dummy";
return rtrn;
}
After this, the restoreState
gets called and property fields can be restored as wanted.
精彩评论