GWT 编辑器和 GXT 网格不发送新创建的代理实体,只有 NULL 值

Posted

技术标签:

【中文标题】GWT 编辑器和 GXT 网格不发送新创建的代理实体,只有 NULL 值【英文标题】:GWT Editor and GXT Grid Not Sending Newly Created Proxy Entities, Only NULL Values 【发布时间】:2012-10-30 13:49:31 【问题描述】:

是否有人可以解决我为什么要通过包含 ListStoreEditor 子编辑器的 GXT 网格将空值保存到服务器实体上的 OneToMany 列表?

我已经按照 Sencha 示例 GridBindingExample 进行了操作。 http://www.sencha.com/examples/#ExamplePlace:gridbinding

public class MyEditor implements IsWidget, Editor<FooProxy> 
    interface Binder extends UiBinder<Widget, MyEditor> 
    private static Binder uiBinder = GWT.create(Binder.class);

    public interface Driver extends SimpleBeanEditorDriver<MyProxy, MyEditor>     
    private Driver driver = GWT.create(Driver.class);

    private ListStore<BarProxy> store;
    ListStoreEditor<BarProxy> items;

    @Ignore
    @UiField(provided = true)
    Grid<BarProxy> grid;

    @Ignore
    @UiField
    ChildEditor childEditor;

    @Override
    public Widget asWidget() 
        MyProperties props = GWT.create(MyProperties.class);
        this.store = new ListStore<BarProxy>(props.key());

        List<ColumnConfig<BarProxy, ?>> columns = new ArrayList<ColumnConfig<BarProxy, ?>>();
        columns.add(new ColumnConfig<BarProxy, String>(props.itemName(), 300, "MyColumn"));

        this.grid = new Grid<BarProxy>(store,new ColumnModel<BarProxy>(columns));
        items = new ListStoreEditor<BarProxy>(store);

        Widget widget = uiBinder.createAndBindUi(this);
        driver.initialize(childEditor);

        childEditor.getCreateButton().addSelectHandler(new SelectHandler() 
            @Override
            public void onSelect(SelectEvent event) 
                RequestContext context = factoryProvider.get().barRequest();
                BarProxy entity = context.create(BarProxy.class);

                entity.setName("Eugene Qtest");
                entity.setAge(45);

                driver.edit(entity);
                store.add(driver.flush());  
                   
        );

        return widget;  
    


public class ChildEditor implements IsWidget, Editor<BarProxy> 
    interface Binder extends UiBinder<Widget, ChildEditor> 
    private static Binder uiBinder = GWT.create(Binder.class);

    @UiField
    TextButton createButton;

    @Override
    public Widget asWidget() 
        return uiBinder.createAndBindUi(this);
    

    public TextButton getCreateButton() 
        return createButton;
    

在我的代码中的上层演示者中,我正在调用:

RequestContext req = editorPresenter.getDriver().flush();
req.fire();

这确实保存了 GWT 编辑器捕获的所有数据元素。在我的数据库中,它确实在上面的代码中为网格创建了行,但是所有的值都是空的,所以当 RequestContext 触发时,持久化会在网格中返回一个空行。因此,没有外键可以将 OneToMany 关系中的实体关联回其父实体。

另外,我查看了对服务器的 JSON 请求和响应,看起来没有任何值正在实体中发送。它可能被混淆了,但它看起来好像其他值是纯文本,所以我认为代理实体值甚至没有被传递。

任何帮助都会很棒!谢谢

【问题讨论】:

【参考方案1】:
            driver.edit(entity);
            store.add(driver.flush());  

这些行的意思是“在编辑器中绘制新对象——好的,取其中放入的任何值并将其添加到存储中”。我不确定这是你想要的。

稍后,您引用了一个editorPresenter,但这似乎不在您的代码中,并且不清楚您何时执行该刷新(甚至是初步的edit() 调用)并触发。您还创建了一个Editor&lt;BarProxy&gt;,但该类型中没有允许编辑的子编辑器。

在您链接到的示例中,混合了两种不同的驱动程序。第一个通过将整个列表传递到 ListStore 来处理整个列表 - 出于示例的目的,这实际上并不是必需的,但可以帮助解释如何将其绑定到更大的案例中,例如 http://www.sencha.com/examples/#ExamplePlace:listpropertybinding例子。该示例实际上应该被视为两个不同的编辑器,具有两个不同的驱动程序 - 在测试时更是如此。首先确保一个工作,并在 driver.flush() 之后返回正确的值,然后另一个。

正如我开始的那样,我认为在edit 调用之后立即调用driver.flush() 几乎肯定不是你想要的,(因为驱动程序没有任何效果),所以从那里开始会很好。然后,如果 是您想要的,请测试当您在服务器上收到调用时,您将获得模型对象及其所有值。

【讨论】:

对不起 Colin,这是虚拟代码,因为真正的代码会占用太多空间。 模型种类是这样分解的。 1. MainModel - ChildOne * List grandChildren - ChildTwo 布局表格以表示模型。因此,当我创建 MainModel 时,我要求服务器通过请求工厂调用创建 MainModel,它将嵌套的 ChildOne 和 ChildTwo 带回给我。所以我想动态地将 GrandChildOne 添加到包含在 ChildOne 中的列表中,并将整个 MainModel 持久保存到带有子和添加的孙子的服务器。希望这能解决问题。 编辑器工作,RequestFactory 在各种情况下也工作 - 看起来你的代码中有些东西要么乱序要么丢失,所以我所能做的就是评论发布的内容。您是否尝试过将 driver.flush() 调用移动到用户完成表单之后?在您当前的小版本中,这显然是一个错误 - 没有看到不起作用的代码,我真的无法提出其他可能没有意义的建议......【参考方案2】:

在上述 cmets 的 Colin 的帮助下,我花了好几天才弄明白,谢谢!

网格填充的原因,但是当您在保存时刷新主编辑器时,值消失并且在网格中插入了一个空白行,因为您必须在编辑器上实现 HasRequestContext 接口以保持相同的 RequestContext会议。以下是我修改后的代码。

public class MyEditor implements IsWidget, Editor<FooProxy>, HasRequestContext<FooProxy> 
    interface Binder extends UiBinder<Widget, MyEditor> 
    private static Binder uiBinder = GWT.create(Binder.class);

    private RequestContext ctx;    

    private ListStore<BarProxy> store;
    ListStoreEditor<BarProxy> items;

    @Ignore
    @UiField(provided = true)
    Grid<BarProxy> grid;

    @Ignore
    @UiField
    ChildEditor childEditor;

    @Override
    public Widget asWidget() 
        MyProperties props = GWT.create(MyProperties.class);
        this.store = new ListStore<BarProxy>(props.key());

        List<ColumnConfig<BarProxy, ?>> columns = new ArrayList<ColumnConfig<BarProxy, ?>>();
        columns.add(new ColumnConfig<BarProxy, String>(props.itemName(), 300, "MyColumn"));

        this.grid = new Grid<BarProxy>(store,new ColumnModel<BarProxy>(columns));
        items = new ListStoreEditor<BarProxy>(store);

        Widget widget = uiBinder.createAndBindUi(this);
        driver.initialize(childEditor);

        childEditor.getCreateButton().addSelectHandler(new SelectHandler() 
            @Override
            public void onSelect(SelectEvent event) 
                RequestContext context = ctx.barRequest();
                BarProxy entity = context.create(BarProxy.class);

                entity.setName("Eugene Qtest");
                entity.setAge(45);

                ctx.edit(entity);
                store.add(entity);  
                   
        );

        return widget;  
    

    @Override
    public void setRequestContext(RequestContext ctx) 
        this.ctx = ctx;     
    

【讨论】:

以上是关于GWT 编辑器和 GXT 网格不发送新创建的代理实体,只有 NULL 值的主要内容,如果未能解决你的问题,请参考以下文章

如何将 Swagger UI 添加到现有的 GXT 或 GWT 项目并使用当前的 GWT-RPC REST 请求?

带有 JAXB 类的 GXT

GWT RPC 和数据转换为 GXT Grid

GWT/GXT 项目中的窗口位置 getParameter 始终为空?

GXT 分页网格

如何防止编辑 GXT ComboBoxCell