如何延迟加载一个uibinded GWT编辑器

时间:2013-02-13 23:59:54

标签: java gwt editor lazy-loading

我想解释GWT编辑器的时间太长(并且尝试可能不准确)。另外,因为我认为自己对编辑机制有基本的了解。所以请不要因为简洁而误导我。

这是我的代码将编辑器var绑定到uibinder模板

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

由于@path规范,似乎不可能延迟加载编辑器。

为了证明这个问题,即使没有延迟加载,但是将这种结构解耦,

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

在GWT.create期间导致错误

  

“找不到吸气剂路径......

我是否可以采取任何措施来允许延迟加载GWT编辑器?

2 个答案:

答案 0 :(得分:2)

您的问题是编辑器生成器会查看返回编辑器的任何方法,因此它会将您的mkShanonEditor方法视为子编辑器的getter。因为它没有@Path,所以它使用方法名称来推断已编辑对象中的路径,尝试mkShanonEditormkShanon,它没有'在你编辑的对象中找到这样的getter。

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

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

答案 1 :(得分:1)

编辑器需要引用窗口小部件才能实际使用它 - 在稍后显示窗体之前输入值。您要求的是编辑器能够注意到shanonEditor为空,并且以某种方式知道稍后再检查(何时?何时分配?当表单可见时?)尝试传入sub再次估价。这没有意义,也不是编辑的工作方式。

相反,请考虑预先填充此字段 - 即不要使其变得懒惰。你现在通过让它变得懒惰而获得了多少 - 你是否懒得在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;
    }
}