2013-02-13 48 views
1

我想這太長了(也許嘗試不準確)來解釋GWT編輯器。另外,因爲我認爲自己對編輯機制有了基本的瞭解。所以請不要爲了簡潔而對我負責。如何延遲加載無聯繫的GWT編輯器

這裏是我的代碼追平了編輯器變種到UiBinder的模板,

@Path("canon.doer") 
@UiField ShenandoerEditor shanonEditor; 

由於@Path規範,這似乎是不可能懶加載編輯器。

爲了說明這個問題,即使沒有延遲加載,但GWT.create

期間去耦建設這個樣子,

@UiFactory ShenandoerEditor mkShanonEditor{ 
    return new ShenandoerEditor(); 
} 

導致錯誤「無法找到吸氣路徑.. 。

有我可以採取允許GWT編輯器的延遲加載任何stragedies?

+0

附錄 - 策略。 – 2013-02-14 04:30:13

回答

2

你的問題是編輯器生成着眼於返回編輯的任何方法,所以它會對待你mkShanonEditor方法一個副總裁的吸氣。因爲它沒有@Path,所以它使用方法名稱來推斷編輯對象內的路徑,嘗試使用mkShanonEditormkShanon,並且它在編輯的對象中找不到這樣的getter。

您只需要用@Editor.Ignore註釋mkShanonEditor

現在,對於延遲加載部分,您必須創建ShenandoerEditor不遲於ValueAwareEditor#setValue,否則編輯器將不會填充它。

+0

聰明智慧的智慧。 – 2013-02-14 15:58:22

1

編輯器需要對小部件進行引用才能實際使用它 - 在稍後顯示錶單之前推入值。你所要求的是,編輯能夠注意到shanonEditor爲空,並且以某種方式知道稍後再檢查(何時?當你分配它時?當表單變得可見時?)以嘗試再次傳遞子值。這沒有意義,也不是編輯如何工作。

相反,考慮預填充此字段 - 即不要讓它懶惰。你現在通過變得懶惰而獲得了多少 - 你是不是把這個懶惰推遲到了createAndBind?你可以只允許創建編輯器,並將面板等離開asWidget/createAndBind?

假設如此,假設你要麼直接實現IsWidget或延長LazyPanel,並且您將幾乎肯定要繪製這些子編輯器(只是不尚未,即等待一小會兒,而不是永遠想要它們),繼續積極地創建葉值編輯器(字段等)和子編輯器(子面板),但是在每個步驟中,都要將這些組成部分實際組裝到一個面板中,直到實際需要爲止。這可能涉及到@UiField(provided=true),表示需要被調用之前createAndBind這些字段填充:

public class CompanyEditor implements Editor<Company>, IsWidget { 
    interface Binder extends UiBinder<Widget, CompanyEditor> {} 
    private static final Binder binder = GWT.create(Binder.class); 

    @UiField(provided = true) 
    TextBox name = new TextBox(); 

    @UiField(provided = true) 
    PersonEditor owner = new PersonEditor(); 

    private Widget root; 

    @Override 
    public Widget asWidget() { 
     if (root == null) { 
      root = binder.createAndBind(this); 
     } 
     return root; 
    } 
} 

public class PersonEditor implements Editor<Person>, IsWidget { 
    interface Binder extends UiBinder<Widget, CompanyEditor> {} 
    private static final Binder binder = GWT.create(Binder.class); 

    @UiField(provided = true) 
    TextBox firstName = new TextBox(); 

    @UiField(provided = true) 
    TextBox lastName = new TextBox(); 

    @UiField(provided = true) 
    @Path("address.city") 
    TextBox city = new TextBox(); 

    private Widget root; 
    @Override 
    public Widget asWidget() { 
     if (root == null) { 
      root = binder.createAndBind(this); 
     } 
     return root; 
    } 
}