1

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

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

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

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

为了演示这个问题,即使没有延迟加载,但像这样解耦构造,

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

在 GWT.create 期间导致错误

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

我可以采取任何策略来允许延迟加载 GWT 编辑器吗?

4

2 回答 2

2

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

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

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

于 2013-02-14T09:43:28.583 回答
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;
    }
}
于 2013-02-14T02:46:40.877 回答