我在我的wicket应用程序中使用PropertyModel和Compoundpropertymodel。我将它们用作局部变量而不是页面类的成员。我是否必须覆盖onDetach()函数以在模型本地时分离它们?或者只是成员变量序列化到会话中?
示例: 的
TextField<String> title = new TextField<String>("title", new PropertyModel<String>(position, "title"));
title.setRequired(true);
form.add(positionTitle);
答案 0 :(得分:3)
我不清楚为什么要分离TextField的模型,因为TextField需要一个模型对象来写入提交的表单值。如果从PropertyModel中分离position
,则TextField将无法在用户提交表单后将其“title”值写入。您可能希望提供有关position
是什么,从何处加载以及在请求周期之间需要分离的原因的更多详细信息。通常的做法是为表单组件设置一个安全可序列化的模型对象,以便将其值写入。
如果确实需要在每个请求结束时分离PropertyModel的模型对象,请将PropertyModel链接到LoadableDetachableModel。 LDM将根据您提供的load()
方法为每个请求周期加载一个新的模型对象,然后在分离时自动将其对该模型对象的引用置空,以防止序列化模型对象。如果使用LoadableDetachableModel<Position>
作为PropertyModel的模型对象,则PropertyModel将自动分离LoadableDetachableModel,这足以避免序列化position
对象。
请注意,您不需要在示例中的模型上显式调用detach()
; Wicket自动分离页面层次结构中所有组件的默认模型。通过“默认模型”,我的意思是一个模型,它被传递到super(...)
链并最终成为model
构造函数之一的Component(...)
参数。
在请求处理结束时,Page会在其子项上调用detach()
(这些孩子会在其子项上调用detach()
,依此类推)。此方法(在Component中定义)调用detachModels()
,后者又分离组件的默认模型。
通常使用多个模型的标准Wicket组件将在detachModels
期间分离其他模型。例如,如果您将DropDownChoice传递给获取/设置所选值的模型以及选择列表的模型,您会注意到DropDownChoice会在每个请求结束时自动分离这两个模型。这是因为AbstractChoice#detachModel()
查找并分离choices
模型(如果已设置)。
链接模型也会分离它们的链式模型,例如,如果你有
Form<User> userForm = new Form<User>("userForm", new CompoundPropertyModel<User>(new DetachableUserModel(...));
然后,detachModels
将自动分离CompoundPropertyModel,这将分离DetachableUserModel。
如果你需要担心手动分离模型,你可以在代码中使用既不是某个组件的默认model
,也不会链接到另一个模型的其他模型。如果要创建具有多个模型对象的新类型的组件,这可能是一个问题。
答案 1 :(得分:2)
在这个例子中,在Wicket中大多数使用这种模型时,初始赋值是局部变量,但是对象被放入 not local的东西中。
您的form
几乎肯定是一个字段或包含在某个内容中,并被序列化到会话中。它包含title
字段,后者又包含模型。
所以它会被序列化,是的,你应该实现onDetach()
。
修改强>
正如评论中所指出的,真正重要的是它是否是页面的组件层次结构的一部分,而不是它是否是一个字段。它在某种程度上相同,因为页面的子组件或任何其他组件都保存在超类children
的字段org.apache.wicket.MarkupContainer
中。
答案 2 :(得分:1)
在你的情况下,我会这样做:
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);
在请求结束时在链中调用detach()
。使用LoadableDetachableModel确保未引用位置对象。
技巧:保持域对象或值对象不可序列化。在开发配置中,如果您有序列化错误,则意味着您保留对这些对象的引用。