等待DOM加载到JSNI GWT中

时间:2012-05-25 17:56:55

标签: javascript gwt dom jsni

我目前遇到的问题是,在DOM完全加载之前,javascript似乎正在执行。我为什么这么说?请使用以下代码:

var $r = $wnd.Raphael("container", 640, 480);

// Creates pie chart at with center at 320, 200,
// radius 100 and data: [55, 20, 13, 32, 5, 1, 2]
$r.piechart(320, 240, 100, [ 55, 20, 13, 32, 5, 1, 2 ]);

返回一个Javascript异常:'f为null'。这似乎表明容器名称无法识别。

如果指定绝对坐标,则饼图会很好。如果我在Chrome控制台中使用之前的代码(加载完毕后),请将饼图加载到容器标记中。

我尝试在JQuery调用中包装代码块:

$wnd.jQuery(function($) {
            // Creates canvas 640 × 480 at 10, 50
            var $r = $wnd.Raphael("container", 640, 480);
            // Creates pie chart at with center at 320, 200,
            // radius 100 and data: [55, 20, 13, 32, 5, 1, 2]
            $r.piechart(320, 240, 100, [ 55, 20, 13, 32, 5, 1, 2 ]);
    });

......没有骰子。

我可以尝试的任何想法吗?

编辑:

以下是我在调用JSNI方法的方式/位置。以下是相关的View代码。

public class WidgetSamplerView extends AbstractPanelView implements
                WidgetSamplerPresenter.Display { 

private FlexTable mainPanel;

public WidgetSamplerView() {
        super();

            mainPanel = new FlexTable();

            HTML container = new HTML();
        container.getElement().setAttribute("style",
                "width:700px;height:700px");
        container.getElement().setId("container");

        mainPanel.setWidget(0, 1, container);

        MyRaphaelWrapper.pieChart(); // JSNI Call

        setWidget(mainPanel);
    }
}

2 个答案:

答案 0 :(得分:3)

您必须确保仅在激活onLoad()时调用JSNI方法,以验证小部件是否已加载。

请参阅another answer of mine on best practices for creating and initializing widgets,以获取快速参考。

基本思想是覆盖窗口小部件上的onLoad()并调用其中的任何加载功能:

public class MainPanel extends FlexTable {

    private Element container;

    public MainPanel() {

        container = DOM.createDiv();
        container.setId("container");

        // this is required by the Widget API to define the underlying element
        setElement(container);
    }

    @Override
    protected void onLoad() {
        super.onLoad();

            MyRaphaelWrapper.pieChart(); // JSNI Call
        }
    }
}

答案 1 :(得分:2)

我怀疑拉斐尔在内部做了以下事情:

document.getElementById("container");

如果您使用标准设置编译GWT应用程序,则代码将加载到iframe中。这就是为什么你必须使用$ wnd而不是window和$ doc而不是document。他们指向主窗口。

你是如何包含其他javascript库的?因为拉斐尔可能正在寻找错误的DOM(iframe的dom)。你能用这样的东西直接将元素传递给rapahel吗?

var c = $doc.getElementById("container");
$wnd.Raphael(c, ..);