简体   繁体   中英

In Wicket, why isn't my results refreshing after form submission?

I'm struggling with a very basic Wicket issue. I'm trying to query a backend database, but can't get the results to display. Below is the code I'm using. currentQuery and currentResult is correctly updated after submission, but my SearchResults class is never rerendered with the new data in currentResults . I suppose that the results class just doesn't notice that the model has in fact been updated. I've been experimenting with modelChanged, but can't get it to work. I'm a bit new to Wicket, so I'm probably doing something fundamental completely wrong. Any help is much appreciated!

public class SearchPage extends WebPage {

Query currentQuery = new Query();
Result currentResult = new Result();

public SearchPage() {
    add(new SearchForm("searchForm", new CompoundPropertyModel<Query>(currentQuery)));
    add(new SearchResults("searchResults", new PropertyModel<List<Hit>>(currentResult, "hits")));
}

public void doSearch(Query Query) {
    currentResult = getResults(query);
}

public class SearchForm extends Form<Query> {
    public SearchForm(String id, CompoundPropertyModel<Query> model) {
        super(id, model);
        add(new TextField<String>("query"));
    }

    protected void onSubmit() {
        super.onSubmit();
        doSearch(currentQuery);
    }
}
public class SearchResults extends WebMarkupContainer {
    public SearchResults(String id, PropertyModel<List<Hit>> model) {
        super(id, model);
        add(new ListView<Hit>("hit", model) {
            protected void populateItem(ListItem<Hit> item) {
                item.add(new Label("column", item.getModelObject().getColumnValue("column")));
            }
        });
    }
}

}

PropertyModel uses reflection to look up the named property on a given target object instance. When you constructed the PropertyModel, you passed it a specific instance of Result, ie the new Result() from SearchPage's constructor. The PropertyModel will continue to hold a reference to that same Result instance from render to render of this page, serializing the Result at the end and then deserializing the Result at the start of each new request cycle (page view). The fact that you later change the page's currentResult variable to reference a different Result instance does not affect which Result instance the PropertyModel uses to look up its model value. Your PropertyModel does not care what currentResult later refers to.

There are two possible solutions that I can think of off the top of my head.

  1. Have the PropertyModel read hits from the actual current value of the Page's currentResult variable:

     new PropertyModel<List<Hit>>(SearchPage.this, "currentResult.hits") 
  2. Use a LoadableDetachableModel to load hits once per request cycle/page view:

     new LoadableDetachableModel<List<Hit>>() { protected Object load() { return getResults(currentQuery); } } 

Note that a LoadableDetachableModel has to be detached at the end of the request cycle or it will never again call getObject() to recalculate the List<Hit> . That said, since your code shows you'd be using it as the default model of the SearchResults component, the SearchResults component would detach the model for you at the end of the request cycle automatically.

I got it working. This seems to be the offending row:

add(new SearchResults("searchResults", new PropertyModel<List<Hit>>(currentResult, "hits")));

The type of the PropertyModel , ie List<Hit> , must have been making the model static. So the only data SearchResults ever saw was the initial object, which was empty.

I changed the line to the below, and updated SearchResult accordingly.

add(new SearchResults("searchResults", new Model<Result>(currentResult, "hits")));

If anyone can explain this further, or feel that I'm incorrect, please comment! In any case, I'm marking my own answer as correct as this solved the problem.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM