I am developing a JSF composite that gets a complex data structure as argument:
<cc:interface componentType="MyComponent">
<cc:attribute name="myModel" required="true" type="my.package.Model" />
</cc:interface>
The backing component processes this model using an init() method that is invoked in the composite via an event:
<cc:implementation>
<f:event type="postAddToView" listener="#{cc.init}" />
[...]
</cc:implementation>
In this init() method I check if the model has already been processed (because I don't want to do that every time the user stays on the page, eg through ajax requests). Hence I store the processed model via StateHelper.put():
public void init()
{
if (getMyModel() == null)
{
MyModel model = processModel(...);
setMyModel(model);
}
}
@SuppressWarnings("unchecked")
public MyModel getMyModel()
{
return (MyModel) getStateHelper().get("MyModel");
}
public void setMyModel(MyModel MyModel)
{
getStateHelper().put("MyModel", MyModel);
}
I expect now, that if the init() method is invoked for example during an Ajax request (in the same view scope) it does not process the model a second time because I have stored it in the view scope via the StateHelper. But no matter what I try, if I click on a command link with void/null outcome the getMyModel() method always returns null. Any ideas?
Implementing the restoreState()
method in the backing component and setting a breakpoint revealed the problem. The postAddToView
event is processed before the invocation of restoreState()
. Using preRenderView
instead resolved the issue for me.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.