如何延迟加载无联系的GWT编辑器

问题描述:

我想这太长了(也许尝试不准确)来解释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

你的问题是编辑器生成着眼于返回编辑的任何方法,所以它会对待你mkShanonEditor方法一个副总裁的吸气。因为它没有@Path,所以它使用方法名称来推断编辑对象内的路径,尝试使用mkShanonEditormkShanon,并且它在编辑的对象中找不到这样的getter。

您只需要用@Editor.Ignore注释mkShanonEditor

现在,对于延迟加载部分,您必须创建ShenandoerEditor不迟于ValueAwareEditor#setValue,否则编辑器将不会填充它。

+0

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

编辑器需要对小部件进行引用才能实际使用它 - 在稍后显示表单之前推入值。你所要求的是,编辑能够注意到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; 
    } 
}