具有覆盖类型问题的GWT单元小部件

时间:2011-01-20 23:32:20

标签: gwt widget overlay data-presentation

我从google developer's guide获取了Cell Table示例,并进行了以下更改:

  • 使用叠加层而不是Java POJO
  • 使用EditTextCell编辑一列

令我惊讶的是,在运行代码时,Cell Table正在为其中的叠加对象添加额外的属性。他们应该看起来像:

{“name”:“John”,“address”:“123 Fourth Road”} {“name”:“Mary”,“address”:“222 Lancer Lane”}

但他们看起来像:

{“name”:“John”,“address”:“123 Fourth Road”,“$ H”:1} {“name”:“Mary”,“address”:“222 Lancer Lane”,“$ H”:2}

以下是演示此问题的修改后的代码:

import java.util.Arrays;
import java.util.List;

import com.google.gwt.cell.client.EditTextCell;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.client.ui.RootPanel;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class Overlay implements EntryPoint {

    private static class Contact extends JavaScriptObject {

        protected Contact() {}

        public static native Contact create(String name, String address) /*-{
            return {"name" : name , "address" : address};
        }-*/;
        public final native String getName() /*-{
            return this["name"];
        }-*/;   
        public final native void setName(String name) /*-{
            this["name"] = name;
        }-*/;
        public final native String getAddress() /*-{
            return this["address"];
        }-*/;   
        public final native void setAddress(String address) /*-{
            this["address"] = address;
        }-*/;
    }

    private static List<Contact> CONTACTS = Arrays.asList(
            Contact.create("John", "123 Fourth Road"),
            Contact.create("Mary", "222 Lancer Lane"));

    /**
     * This is the entry point method.
     */
    public void onModuleLoad() {

        CellTable<Contact> table = new CellTable<Contact>();
        // Create name column.
        Column<Contact, String> nameColumn = new Column<Contact, String>(new EditTextCell()) {
            public String getValue(Contact object) {
                return object.getName();
            }
        };
        // Create address column.
        TextColumn<Contact> addressColumn = new TextColumn<Contact>() {
            public String getValue(Contact contact) {
                return contact.getAddress();
            }
        };
        // Add the columns.
        table.addColumn(nameColumn, "Name");
        table.addColumn(addressColumn, "Address");      
        table.setRowCount(CONTACTS.size(), true);
        // Push the data into the widget.
        printList();
        table.setRowData(0, CONTACTS);      
        printList();        
        RootPanel.get().add(table);
    }

    private void printList() {
        for(Contact contact : CONTACTS) {
            GWT.log(new JSONObject(contact).toString());
        }
    }

}

我已检查过导致问题的可编辑列。如果我删除它,表格不会修改我的叠加层。

无论如何,这是一种非常奇怪的行为。如果您的小部件可以添加意外的属性,我觉得使用叠加层是不安全的。

之前是否有人遇到此问题或者此行为是否记录在任何地方?任何解决方法的提示?

非常感谢

2 个答案:

答案 0 :(得分:1)

此问题的正确答案已发布在GWT开发论坛(link)中:

  

$ H属性来自   实施   JavaScriptObject #hashCode()(in   com.google.gwt.cire.client.impl.Impl#GetHashCode的(对象))。

     

在您的情况下,这是由于   AbstractEditableCell维护一张地图   值键的“视图数据”,   以及你对默认的使用(我猜)   提供Key实现   (SimpleProvidesKey)直接   返回该项目。

     

因此,在渲染时,EditTextCell   调用getViewData,查找   键入地图(因此需要   密钥的哈希码,因此调用   hashCode),关键是你的JSO   (因此新的$ H财产)。

     

我相信提供一个ProvideKey   实施(在你的情况下,返回   例如,名称属性)   Celltable将解决您的问题。

答案 1 :(得分:0)

我怀疑CellTable可以偷偷编辑你的JSON。检查Firebug / Chrome_Developer_Tools /中的那些叠加层......如果它们没问题那么很可能就是这行中的错误:

GWT.log(new JSONObject(contact).toString());

JSONObject.toString至少有两个问题:Passing List to/from JSNI works in web mode but fails in hosted mode&amp; toString() and JSNI
在第二期中,有comment根据您可以尝试这样做:

GWT.log( (String) new JSONObject(contact) );