GWT:将自定义小部件添加到celltable丢失自定义小部件的事件 [英] GWT: On adding custom widget to celltable losing events of the custom widgets

查看:126
本文介绍了GWT:将自定义小部件添加到celltable丢失自定义小部件的事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

pre $ $ $ c $ if>(viewData.isEditing()){
textBoxSelector.setText(text) ;
OnlyToBeUsedInGeneratedCodeStringBlessedAsSafeHtml safeHtmlObj = new OnlyToBeUsedInGeneratedCodeStringBlessedAsSafeHtml(textBoxSelector.toString());
sb.append(safeHtmlObj);
} else {
//用户按下回车键,但查看数据仍然存在。
sb.append(html);
}

如果我尝试在渲染器中添加小部件()方法使用下面的代码,它不会添加widget。

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

$ / code>

如果有人能指导我实现widget的添加, CellTable ,而不会丢失相关事件。

解决方案

GWT的单元格与GWT Widgets不兼容。这意味着你不能将GWT小部件放置在单元格内并使其仍然有效。单元格确实有一个可选的事件处理机制(详见下文)

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



在您的上面的例子中,你调用someWidget.toString()。这样做只会返回小部件的HTML表示形式,并且会导致您的事件处理失败。



处理单元格中的事件



自定义单元格的GWT开发指南(有一些额外的细节)

要处理单元格中的事件,您需要重写一个名为 onBrowserEvent 的单独方法。您还需要通过在您的构造函数中调用 super('click','keydown')来将您的单元格配置为通知特定事件有兴趣听。

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



以下是上述链接开发指南中的示例:

  @Override 
public void onBrowserEvent(
上下文上下文,
元素父元素,
字符串值,
NativeEvent事件,
ValueUpdater< String> valueUpdater){

//让AbstractCell处理keydown事件。
super.onBrowserEvent(context,parent,value,event,valueUpdater);

//处理单击事件。
if(click.equals(event.getType())){
//忽略发生在最外层元素之外的点击。
EventTarget eventTarget = event.getEventTarget();
if(parent.getFirstChildElement()。isOrHasChild(Element.as(eventTarget))){
doAction(value,valueUpdater);
}
}
}


Our requirement is to make an editable grid using the CellTable containing custom widgets in its cell. The custom widget is having text box and search button associated with the text box. To add the custom widget as a cell created a subclass of AbstractEditableCell class (provided by GWT) and had override render() and onBrowserEvent() methods.

The render(Context context, String value, SafeHtmlBuilder sb) method of the custom widget cell creates a Safe html for the widget and render this safe html in to the cell. But the problem i am facing is, the custom widget is rendered correctly but it loses its associates events. The render method in given below :

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);
}

If I try to add the widget in the render() method using the following code, it does not add the widget.

    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);
    }

I'd really appreciate if anyone can guide me in achieving addition of widget in the CellTable without it losing associated events.

解决方案

GWT's Cells are non-compatible with GWT Widgets. This means that you could not have a GWT widget placed inside of a cell and have it still function. Cells do have an alternative event handling mechanism though (covered below)

The reason for this is that Cells are closer to stateless renderers. Given a data object the Cell will spit out HTML. A single Cell will be reused over and over - spitting out HTML for various elements on the page - and never maintaining references to any of the DOM elements it creates.

In your above example, you call "someWidget.toString()". Doing this will only return the HTML representation of your widget and is what is loses your event handling.

Handling Events in Cells

GWT Dev Guide for Custom Cells (has some additional details)

To handle events in cells, you'll need to override a separate method called onBrowserEvent. You'll also need to configure your cell to be notified of particular events by calling super('click', 'keydown') in your constructor with the list of events you are interested in listening to.

Since Cells are stateless renderers, the onBrowserEvent will be passed a context of the rendered element that was clicked on along with the original data object that your cell rendered. You can then apply changes or manipulate the DOM as needed.

Here is an example taken from the linked dev guide above:

@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);
    }
  }
}

这篇关于GWT:将自定义小部件添加到celltable丢失自定义小部件的事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆