简体   繁体   English

如果局部变量中使用了检票口模型,是否必须分离检票口模型?

[英]Do i have to detach wicket models, if they are used in local variables?

I am using PropertyModel and Compoundpropertymodel in my wicket application. 我在检票口应用程序中使用PropertyModel和Compoundpropertymodel。 I use them as local variables and not as members of the page classes. 我将它们用作局部变量,而不用作页面类的成员。 Do i have to override the onDetach() Function to detach the models when they are local? 我必须重写onDetach()函数以在模型处于本地状态时分离它们吗? Or are only member variables serialized into the session? 还是仅将成员变量序列化到会话中?

Example: 例:

TextField<String> title = new TextField<String>("title", new PropertyModel<String>(position, "title"));
title.setRequired(true);
form.add(positionTitle);

It's not clear to me why you want to detach the model of your TextField, as a TextField needs a model object to write submitted form values to. 我不清楚您为什么要分离TextField的模型,因为TextField需要模型对象才能将提交的表单值写入其中。 If you detach position from the PropertyModel, then the TextField won't have a place to write its "title" value to after the user submits the form. 如果您从PropertyModel分离position ,则在用户提交表单后,TextField将没有位置写入其“ title”值。 You might want to provide more details about what position is, where it was loaded from, and why it needs to be detached between request cycles. 您可能想提供更多有关position ,从何处装载以及为什么需要在请求周期之间分离的详细信息。 Common practice is to have a safely serializable model object for form components to write their values to. 通常的做法是为表单组件提供一个安全可序列化的模型对象,以将其值写入其中。

If you do need to detach the model object of a PropertyModel at the end of each request, chain the PropertyModel to a LoadableDetachableModel. 如果确实需要在每个请求结束时分离PropertyModel的模型对象,请将PropertyModel链接到LoadableDetachableModel。 LDM will load a fresh model object for each request cycle based on your provided load() method, and will then automatically null out its reference to that model object on detach to prevent serializing the model object. LDM将根据您提供的load()方法为每个请求周期加载一个新的模型对象,然后在分离时自动将其对该模型对象的引用归零,以防止序列化模型对象。 If you use a LoadableDetachableModel<Position> as the model object of your PropertyModel, then the PropertyModel will detach the LoadableDetachableModel automatically and that will be enough to avoid serializing the position object. 如果将LoadableDetachableModel<Position>用作PropertyModel的模型对象,则PropertyModel将自动分离LoadableDetachableModel,这将足以避免序列化position对象。

Note that you do not need to explicitly call detach() on models like the one in your example; 注意,您不需要像示例中那样在模型上显式调用detach() Wicket detaches the default models of all Components in the Page hierarchy automatically. Wicket会自动分离Page层次结构中所有组件的默认模型。 By "default model", I mean a model that gets passed up the super(...) chain and eventually becomes the model argument of one of the Component(...) constructors. “默认模型”是指一个模型,该模型沿super(...)链传递,并最终成为Component(...)构造函数之一的model参数。

At the end of request processing, the Page calls detach() on its children (and those children call detach() on their children and so on). 在请求处理结束时,页面在其子代上调用detach() (这些子代在其子代上调用detach()依此类推)。 This method (defined in Component) calls detachModels() , which in turn detaches the default model of the Component. 此方法(在Component中定义)调用detachModels() ,这又分离了Component的默认模型。

Standard Wicket components that commonly use more than one model will detach additional models during detachModels . 通常使用多个模型的标准Wicket组件将在detachModels期间分离其他模型。 For example, if you pass DropDownChoice both a model to get/set the selected value, and a model of the list of choices, you will notice that DropDownChoice automatically detaches both of these models at the end of each request. 例如,如果您同时传递DropDownChoice和一个用于获取/设置所选值的模型以及一个选项列表的模型,则您会注意到DropDownChoice在每个请求结束时自动分离这两个模型。 This is because AbstractChoice#detachModel() looks for and detaches a choices model, if one has been set. 这是因为AbstractChoice#detachModel()查找并分离choices模型(如果已设置)。

Chaining models also detach their chained models, so for example if you had 链接模型还会分离其链接的模型,例如,如果您有

Form<User> userForm = new Form<User>("userForm", new CompoundPropertyModel<User>(new DetachableUserModel(...));

then the CompoundPropertyModel would be detached automatically by detachModels , and that would in turn detach the DetachableUserModel. 那么CompoundPropertyModel将由detachModels自动分离,这又将分离detachModels

Where you DO need to worry about manually detaching models is any case where you use additional models in your code that are neither the default model of some component, nor chained into another model that is. 在任何情况下,您都需要担心手动分离模型的情况是,您在代码中使用了其他模型,这些model既不是某些组件的默认model ,也不是链接到其他模型的模型。 This might be a concern if you are creating a new type of Component that has more than one model object. 如果要创建一种具有多个模型对象的新型Component,这可能是一个问题。

In this instance, and in most uses of such models in Wicket, the initial assignment is to a local variable, but the object is put into something that is not local. 在这种情况下,在Wicket中此类模型的大多数使用中,初始分配是分配给局部变量,但是对象被放入局部对象中。

Your form is almost certainly a field or contained in something that is, and is serialized into the session. 您的form几乎可以肯定是一个字段,或者包含在其中,并被序列化到会话中。 It contains the title field, which in turn contains the model. 它包含title字段,而title字段又包含模型。

So it will be serialized, and yes you should probably implement onDetach() . 因此它将被序列化,是的,您可能应该实现onDetach()

Edit: 编辑:

As noted in a comment, what really matters is whether it is part of the component hierarchy of a page, rather than whether it is a field. 如评论中所述,真正重要的是它是否是页面的组件层次结构的一部分,而不是它是否是字段。 It does on some level amount to the same thing, as the child components of a page or any other component are held in a field children in the superclass org.apache.wicket.MarkupContainer . 它在某种程度上起到了相同的作用,因为页面的子组件或任何其他组件都保存在超类org.apache.wicket.MarkupContainer中的字段children组件中。

In your case, I would do : 就您而言,我会做:

    IModel model = new CompoundPropertyModel(new LoadableDetachableModel(position){
        @Override protected Object load() { return null; }
    });
    Form form = new Form("form", model);
    form.add(
            new TextField("title")
                .setRequired(true));
    add(form);

The detach() are called in chain at the end of the request. 在请求结束时,将在链中调用detach() Using a LoadableDetachableModel ensure that the position object is not referenced. 使用LoadableDetachableModel确保未引用位置对象。

A trick: keep you domain object or value object non serializable. 技巧:使域对象或值对象不可序列化。 In development configuration, if you have serialization errors, it means that you keep references on these objects. 在开发配置中,如果遇到序列化错误,则意味着您保留对这些对象的引用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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