leclerc cyril created WICKET-6987:
-------------------------------------
Summary: Panel replace method detach parent model
Key: WICKET-6987
URL: https://issues.apache.org/jira/browse/WICKET-6987
Project: Wicket
Issue Type: Bug
Components: wicket
Affects Versions: 9.10.0
Reporter: leclerc cyril
In a page (extends {*}webPage{*}) when we replace a component in a panel, and
when it remove the old component, the method detach will detach the parent
model instead of it own model if present. it cause a reload of the model when
the new composant is added.
So imagine you have a panel with 20 components using 1 detachablemodel (wit
some db queries), all use the same model loaded once on the first *_getModel_*
call , then all components will use same model value, and then detach is called
=> ok
But if we have a button will submit a form, and we create new components and
replace in our panel, on each replace method, the remove method will detach
parent model, so then on each component it will load the model (so 20x load
model called)
How to reproduce ?
take a helloworld projet, create a panel with one component Label using a
detachable string model
in HomePage constructor set panel
add a form et onsubmit replace the panel (1 or N time you want) with the same
component
{code:java}
public class HomePage extends WebPage {
private static final long serialVersionUID = 1L;
Panel panel ;
IModel<String> formModel = Model.of("");
IModel<String> model = new LoadableDetachableModel<String>() {
@Override
protected String load() {
return formModel.getObject();
}
@Override
protected void onDetach() {
super.onDetach();
}
};
public HomePage(final PageParameters parameters) {
super(parameters);
final var form = new Form<>( "form" ){
@Override
protected void onSubmit(){
System.out.println("submitted");
panel.replace( new Label( "test", model ) );
}
};
add( form );
form.add(new TextField("field", formModel ) );
form.add( new Label( "result", model) );
form.add(new Label("version",
getApplication().getFrameworkSettings().getVersion()));
panel = new HomePanel( "homePanel");
panel.add( new Label( "test", model) );
form.add(panel);
}
} {code}
and in panel
{code:java}
public class HomePanel extends Panel { Label label; public HomePanel(String id)
{ super( id ); } public HomePanel(String id, IModel<String> model) { super( id,
model ); label = new Label( "test", model.getObject() ); add( label ); } }
{code}
in home page html
{code:java}
<input type="text" wicket:id="field">
<div class="col-12"><button type="submit" class="btn btn-primary"><i class="fas
fa-sync">SUBMIT</i></button></div>
Result: <span wicket:id="result">dummy name</span><br/> {code}
in panel html
{code:java}
<wicket:panel xmlns:wicket="http://wicket.apache.org">
User: <span wicket:id="test">dummy name</span><br/>
</wicket:panel> {code}
to go further on getModelImpl() (in component.java) we retrieve the first
element in data object:
{code:java}
IModel<?> getModelImpl()
{
if (getFlag(FLAG_MODEL_SET))
{
return (IModel<?>)data_get(0); (this causing detach of the parent page
model)
}
return null;
} {code}
--
This message was sent by Atlassian Jira
(v8.20.7#820007)