[英]Do i have to detach wicket models, if they are used in local variables?
我在檢票口應用程序中使用PropertyModel和Compoundpropertymodel。 我將它們用作局部變量,而不用作頁面類的成員。 我必須重寫onDetach()函數以在模型處於本地狀態時分離它們嗎? 還是僅將成員變量序列化到會話中?
例:
TextField<String> title = new TextField<String>("title", new PropertyModel<String>(position, "title"));
title.setRequired(true);
form.add(positionTitle);
我不清楚您為什么要分離TextField的模型,因為TextField需要模型對象才能將提交的表單值寫入其中。 如果您從PropertyModel分離position
,則在用戶提交表單后,TextField將沒有位置寫入其“ title”值。 您可能想提供更多有關position
,從何處裝載以及為什么需要在請求周期之間分離的詳細信息。 通常的做法是為表單組件提供一個安全可序列化的模型對象,以將其值寫入其中。
如果確實需要在每個請求結束時分離PropertyModel的模型對象,請將PropertyModel鏈接到LoadableDetachableModel。 LDM將根據您提供的load()
方法為每個請求周期加載一個新的模型對象,然后在分離時自動將其對該模型對象的引用歸零,以防止序列化模型對象。 如果將LoadableDetachableModel<Position>
用作PropertyModel的模型對象,則PropertyModel將自動分離LoadableDetachableModel,這將足以避免序列化position
對象。
注意,您不需要像示例中那樣在模型上顯式調用detach()
; Wicket會自動分離Page層次結構中所有組件的默認模型。 “默認模型”是指一個模型,該模型沿super(...)
鏈傳遞,並最終成為Component(...)
構造函數之一的model
參數。
在請求處理結束時,頁面在其子代上調用detach()
(這些子代在其子代上調用detach()
依此類推)。 此方法(在Component中定義)調用detachModels()
,這又分離了Component的默認模型。
通常使用多個模型的標准Wicket組件將在detachModels
期間分離其他模型。 例如,如果您同時傳遞DropDownChoice和一個用於獲取/設置所選值的模型以及一個選項列表的模型,則您會注意到DropDownChoice在每個請求結束時自動分離這兩個模型。 這是因為AbstractChoice#detachModel()
查找並分離choices
模型(如果已設置)。
鏈接模型還會分離其鏈接的模型,例如,如果您有
Form<User> userForm = new Form<User>("userForm", new CompoundPropertyModel<User>(new DetachableUserModel(...));
那么CompoundPropertyModel將由detachModels
自動分離,這又將分離detachModels
。
在任何情況下,您都需要擔心手動分離模型的情況是,您在代碼中使用了其他模型,這些model
既不是某些組件的默認model
,也不是鏈接到其他模型的模型。 如果要創建一種具有多個模型對象的新型Component,這可能是一個問題。
在這種情況下,在Wicket中此類模型的大多數使用中,初始分配是分配給局部變量,但是對象被放入非局部對象中。
您的form
幾乎可以肯定是一個字段,或者包含在其中,並被序列化到會話中。 它包含title
字段,而title
字段又包含模型。
因此它將被序列化,是的,您可能應該實現onDetach()
。
編輯:
如評論中所述,真正重要的是它是否是頁面的組件層次結構的一部分,而不是它是否是字段。 它在某種程度上起到了相同的作用,因為頁面的子組件或任何其他組件都保存在超類org.apache.wicket.MarkupContainer
中的字段children
組件中。
就您而言,我會做:
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確保未引用位置對象。
技巧:使域對象或值對象不可序列化。 在開發配置中,如果遇到序列化錯誤,則意味着您保留對這些對象的引用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.