GWT:将自定义窗口小部件添加到自定义窗口小部件的单元格丢失事件

时间:2011-08-03 08:42:38

标签: gwt

我们的要求是使用其单元格中包含自定义小部件的CellTable制作可编辑网格。自定义窗口小部件具有与文本框关联的文本框和搜索按钮。要将自定义窗口小部件添加为单元格,请创建AbstractEditableCell类的子类(由GWT提供),并使用覆盖render()onBrowserEvent()方法。

自定义窗口小部件单元格的render(Context context, String value, SafeHtmlBuilder sb)方法为窗口小部件创建一个安全html,并将此安全html呈现给单元格。但我面临的问题是,自定义窗口小部件正确呈现但它失去了其关联事件。下面给出的渲染方法:

if (viewData.isEditing()) {
    textBoxSelector.setText(text);
    OnlyToBeUsedInGeneratedCodeStringBlessedAsSafeHtml safeHtmlObj = new OnlyToBeUsedInGeneratedCodeStringBlessedAsSafeHtml(textBoxSelector.toString());
    sb.append(safeHtmlObj);
} else {
  // The user pressed enter, but view data still exists.
  sb.append(html);
}

如果我尝试使用以下代码在render()方法中添加小部件,则不会添加小部件。

    int left = parent.getAbsoluteLeft();
    int top = parent.getAbsoluteTop();
    String elementId = "ID" + left + top;
    try {
        parent.setId(elementId);
        // parent.removeFromParent();
        RootPanel.get(elementId).add(textBoxSelector);
    } catch (AssertionError error) {
        RootPanel.get(elementId).add(textBoxSelector);
    }

如果有人能指导我在CellTable中添加小部件而不丢失相关事件,我真的很感激。

1 个答案:

答案 0 :(得分:5)

GWT的Cell与GWT Widgets不兼容。这意味着您无法将GWT窗口小部件放置在单元格内并使其仍然起作用。虽然单元格确实具有替代事件处理机制(如下所述)

原因是Cell更接近无状态渲染器。给定一个数据对象,Cell将吐出HTML。单个Cell将被重复使用 - 为页面上的各种元素吐出HTML - 并且永远不会维护对它创建的任何DOM元素的引用。

在上面的示例中,您调用“someWidget.toString()”。这样做只会返回窗口小部件的HTML表示,并且会丢失您的事件处理。

处理单元格中的事件

GWT Dev Guide for Custom Cells(有一些额外的细节)

要处理单元格中的事件,您需要覆盖名为onBrowserEvent的单独方法。您还需要通过在构造函数中使用您有兴趣收听的事件列表调用super('click', 'keydown')来配置您的单元格以通知特定事件。

由于Cells是无状态渲染器,onBrowserEvent将传递被单击的渲染元素的上下文以及单元格渲染的原始数据对象。然后,您可以根据需要应用更改或操作DOM。

以下是从上面链接的开发指南中获取的示例:

@Override
public void onBrowserEvent(
    Context context,
    Element parent,
    String value,
    NativeEvent event,
    ValueUpdater<String> valueUpdater) {

  // Let AbstractCell handle the keydown event.
  super.onBrowserEvent(context, parent, value, event, valueUpdater);

  // Handle the click event.
  if ("click".equals(event.getType())) {
    // Ignore clicks that occur outside of the outermost element.
    EventTarget eventTarget = event.getEventTarget();
    if (parent.getFirstChildElement().isOrHasChild(Element.as(eventTarget))) {
      doAction(value, valueUpdater);
    }
  }
}