在 Wicket 中,为什么我的结果在提交表单后没有刷新?

发布于 2024-11-02 22:14:35 字数 1479 浏览 2 评论 0 原文

我正在努力解决一个非常基本的 Wicket 问题。我正在尝试查询后端数据库,但无法显示结果。下面是我正在使用的代码。 currentQuerycurrentResult 在提交后正确更新,但我的 SearchResults 类永远不会使用 currentResults 中的新数据重新呈现。我想结果类只是没有注意到模型实际上已经更新了。我一直在尝试 modelChanged,但无法让它发挥作用。我对 Wicket 有点陌生,所以我可能做了一些根本性的完全错误的事情。非常感谢任何帮助!

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")));
            }
        });
    }
}

}

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")));
            }
        });
    }
}

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

弄潮 2024-11-09 22:14:35

PropertyModel 使用反射来查找给定目标对象实例上的命名属性。当您构建 PropertyModel 时,您向它传递了 Result 的特定实例,即来自 SearchPage 构造函数的 new Result()。从渲染到此页面的渲染,PropertyModel 将继续保留对同一 Result 实例的引用,在最后序列化 Result,然后在每个新请求周期(页面视图)开始时反序列化 Result。您稍后更改页面的 currentResult 变量以引用不同的 Result 实例这一事实不会影响 PropertyModel 使用哪个 Result 实例来查找其模型值。您的 PropertyModel 并不关心 currentResult 稍后引用的内容。

我能立即想到两种可能的解决方案。

  1. 让 PropertyModel 从页面 currentResult 变量的实际当前值读取点击

    new PropertyModel>(SearchPage.this, "currentResult.hits")
    
  2. 使用LoadableDetachableModel 在每个请求周期/页面视图中加载一次点击

    new LoadableDetachableModel>()
    {
        受保护对象加载()
        {
            返回 getResults(currentQuery);
        }
    }
    

请注意,LoadableDetachableModel 必须在请求结束时分离循环,否则它将永远不会再次调用 getObject() 来重新计算 List。也就是说,由于您的代码显示您将使用它作为 SearchResults 组件的默认模型,因此 SearchResults 组件会在搜索结束时为您分离模型。自动请求循环。

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, i.e. 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.

泅人 2024-11-09 22:14:35

我成功了。这似乎是有问题的行:

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

PropertyModel 的类型,即List,必须使模型静态。因此,SearchResults 看到的唯一数据是初始对象,它是空的。

我将该行更改为以下内容,并相应地更新了 SearchResult

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

如果有人能进一步解释这一点,或者觉得我不正确,请评论!无论如何,我将自己的答案标记为正确,因为这解决了问题。

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, i.e. 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文