簡體   English   中英

如果局部變量中使用了檢票口模型,是否必須分離檢票口模型?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM