javascript - GWT UiBinder - 渲染模板后执行 JS?

标签 javascript java templates gwt

我的 UiBinder 模板中有一个 ID 为“test”的 div,并且想要在其上执行一些 jQuery 内容。如果我在 UiBinder java 类末尾执行 native 方法,则 javascript 调用会失败,因为 div 似乎还不存在:

public MyWidget() {
    initWidget(uiBinder.createAndBindUi(this));
    AppUtils.initializeSomething();
}

解决方法是使用计时器并稍微延迟我的 JS 代码。这可行,但在我看来相当丑陋。如果 UiBinder 模板完全加载,是否有任何干净的解决方案来执行我的 javascript?

public MyWidget() {
    initWidget(uiBinder.createAndBindUi(this));

    new Timer(){
        @Override
        public void run() {
            AppUtils.initializeSomething();
        };
    }.schedule(1000);

}

native 方法:

public static native void initializeSomething()/*-{

     $wnd.$('#test').doSomeJsStuff();
}-*/;

最佳答案

public MyWidget() {
    initWidget(uiBinder.createAndBindUi(this));
    AppUtils.initializeSomething();
}

由于这只是构造函数,此时 DOM 元素都存在,但尚未附加,因此任何尝试查找附加 dom 元素的代码都将失败(例如,jQuery 将尝试执行 document.getElementById 来计算 $('#test'),这将失败,因为小部件尚未附加到文档。

相反,您有两个基本选择:

  • 立即运行初始化,但实际上传入 dom 元素,而不是尝试查找它(并失败),或者
  • 等到 dom 元素实际附加后再尝试初始化。
<小时/>

运行初始化只需知道要修改哪个元素即可。由于您使用的是 uiBinder,因此您可以在 Java 类中创建一个 Element 字段,并要求将其分配给某个设置了 ui:field 属性的元素同名。这就像您当前将元素的 ID 设置为“test”,然后期望使用 `$('#test') 找到它。像这样的事情:

在您的 .ui.xml 文件中:

<g:HTMLPanel>
  <div ui:field="testElement">...</div>
  ...
</g:HTMLPanel>

在您的 .java 类中:

@UiField Element testElement;

然后在 JSNI 方法中,您可以传入元素或在调用它时引用它。您的 initializeSomething 和构造函数可能如下所示:

public MyWidget() {
    initWidget(uiBinder.createAndBindUi(this));
    AppUtils.initializeSomething(this.testElement);
}
public static native void initializeSomething(Element elt)/*-{
    //jQuery lets you wrap a dom element instead of finding it,
    //and we already know where it is
    $wnd.$(elt).doSomeJsStuff();
}-*/;
<小时/>

接下来,等待附加到 DOM 来运行 doSomeJsStuff() - 两种简单的方法。在原始 JS 中,您可以使用第一种方法,尽管我认为这对于 JS 来说是非常错误的。所以这是第一种错误的方法:

//make the elements
MyWidget widget = new MyWidget();
//attach them to the dom (note that if you attach to a different
//                        parent, that parent too must be attached
//                        and so on).
RootPanel.get().add(widget);
//now that we are attached, run the setup code!
widget.doSomeJsStuff();

这显然很愚蠢 - 我们正在编写一个类,该类应该足够聪明,能够照顾自己!

让我们再试一次,这次指示类在附加后运行 doSomeJsStuff()。有两种方法可以完成这项工作,onAttachonLoad - 没有关于 doSomeJsStuff 做什么的具体细节,我不知道什么您需要,但 onLoad 更容易使用。

值得注意的是,每次附加小部件时都会调用这些方法,而不仅仅是第一次。如果这对您很重要,您可能需要检查该小部件是否尚未附加。如果没有,我们需要的是:

@Override
protected void onLoad() {
  doSomeJsStuff();
}

关于javascript - GWT UiBinder - 渲染模板后执行 JS?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31010704/

相关文章:

java - 使用集合映射

java - 如何在 JMenu 中激活 ActionEvent 以在框架上显示新面板?(基本)

c++ - 如何在 C++ 中显式实例化模板构造函数?

java - 用于匹配短于 n 个字符的字符串的复杂正则表达式

c++ - 模板之间的隐式转换

wordpress - Noob问题:Wordpress循环

带有 vert.x stomp 服务器的 Javascript Stomp 客户端

javascript - 正则表达式匹配任何 Javascript/jQuery 函数声明行

javascript - Prop 未传递给 onClick 函数

javascript - 如何在选择框onclick中调用servlet