GWT Widget未在DOM中正确设置

时间:2012-12-03 21:59:11

标签: gwt dom printing

我想打印一个扩展Composite的GWT小部件。这个小部件由一个网格组成,其网格单元是用ListDataProvider构建的。当用户在按钮上打印时,将构建要打印的小部件。完成后,我启动打印:

    Element element = widgetToPrint.getElement();
    String content = element.getInnerHTML();
    print(content);


    public static native boolean print(String content)
    /*-{
    var mywindow = window.open('', 'Printing', '');
    mywindow.document.write('<html><head><title>Test</title>');
    mywindow.document.write('<link rel="stylesheet" href="/public/stylesheets/ToPrintWidget.css" type="text/css" media="all"/></head><body>');
    mywindow.document.write(content);
    mywindow.document.write('</body></html>');
    mywindow.print();
    return true;
    }-*/;

所以,这是我的问题:

通过此方法打开的窗口包含窗口小部件的核心(由UI Binder构建),但是有些孩子丢失...

如果我查看ListDataProvider及其相关的FlowPanel,数据是一致的,即我的列表和flowPanel中有几个项目。

因此,它应该在打印窗口上可见... 我认为问题可能与用于打印小部件的方法有关,因此我也尝试在启动打印之前将此小部件添加到对话框中,以查看小部件是否已正确构建...并且它是。< / p>

所以我的小部件在对话框上显示得很好,但是如果我尝试将其innerHTML赋予print方法,使用getElement(),一些小部件就会丢失......我觉得这些小部件应该是当ListDataProvider更改未在DOM中正确设置时构建...当我将小部件添加到常规组件时它以某种方式工作,但是当我必须直接给它的innerHTML时它不起作用...

你有什么想法吗?

提前致谢。

4 个答案:

答案 0 :(得分:2)

窗口小部件不仅仅是它们元素的总和,而且DOM元素不仅仅是它们被序列化的字符串。窗口小部件是元素,所有事件都会沉入dom,以监听用户的任何更改或交互。然后,元素具有当用户与它们交互时调用的回调函数或处理程序。

通过序列化元素(即调用getInnerHTML()),您只能读出dom​​的结构,而不是回调,而且不是CSS设置的样式。这可能不应该被认为是正常的,并且正如你的经验所证明的那样,事实并非如此。

由于这只是您尝试创建的打印窗口,因此事件处理可能不是问题。您只是希望能够查看但不与该组窗口小部件中的内容进行交互。样式可能是当时的主要问题(虽然你的问题没有指明'有些孩子失踪'并没有告诉我们缺少什么,或者给我们提供更多关于为什么......的线索) - 你正在添加一个样式表在您的JSNI代码中,但是CellTable(我假设您在引用ListDataProvider时使用它)需要额外的CssResource实例才能正确显示。我不知道你怎么能在新窗口中劫持那些人。

您是否仅使用它来打印内容,而不是让用户直接与数据交互?如果是这样,请考虑另一种方法 - 使用SafeHtmlBuilder创建一个巨大的,正确转义的内容字符串,以便在新窗口中绘制。

答案 1 :(得分:0)

您可能想要抓取外部HTML 而不是内部

GWT遗憾的是没有getOuterHTML,但模仿相对容易。

  • 如果您的窗口小部件是元素中唯一的子窗口,那么只需获取父元素的内部HTML(w.getElement().getParentElement().getInnerHTML()
  • 否则,克隆您的小部件节点将其添加到新创建的父元素,您将从中获取内部HTML:

    DivElement temp = Document.get().createDivElement();
    temp.appendChild(w.getElement().cloneNode(true));
    return temp.getInnerHTML();
    

答案 2 :(得分:0)

String content = element.toString();

这将包括节点中的所有层次结构元素。

提醒一下,所有GWT处理程序都不起作用,你必须使用DOM接收所有事件。

答案 3 :(得分:0)

首先感谢您的回答,它帮助我解决了这个问题。 我几乎解决了这个问题:

首先,我不再使用ListDataProvider,因为我不清楚视图何时以及如何刷新。相反,我手工添加我的小部件,这是有道理的,因为它们无论如何都不会移动。

然后,我使用常见的CSS样式表定义我的小部件的样式。但是,为了做到这一点,我不能依赖CssResource,这是我习惯用GWT做的方式。我认为这来自JS方法,它被这种样式迷失了......相反,我必须在静态CSS样式表中指定所有内容,并将其提供给JS。

它运作得非常好,即我有我的小部件,有i样式,我可以打印出来。

但是... 某些小部件的颜色取决于它们所代表的对象的颜色。因此,我不能写一个通用的CSS样式表......正如我所说,我不能使用CssResource添加一个样式......你对处理它的方式有什么想法吗?

为了确保我在添加样式的方式上很清楚,这里有一个例子:

    Label l = new Label("Here is a cell in my grid to be printed");
    l.addStyleName("PrintLineCell-kind_1");

使用公共CSS样式表:

    .PrintLineCell-kind_1{
        background-color: red;
    }

我希望有一种更好的方法,而不是写300种样式来覆盖300种不同的颜色......