【问题标题】:How can the name of a container tag id matter?容器标签 ID 的名称有什么关系?
【发布时间】:2012-01-16 01:10:54
【问题描述】:

我正在编写一个 GWT/GAE(Java) 应用程序。 GWT 自带的自动生成的 hello word 示例生成如下代码:

<table align="center">

  <tr>
    <td colspan="2" style="font-weight:bold;">Please enter your name:</td>
  </tr>

  <tr>
    <td id="nameFieldContainer"></td>
    <td id="sendButtonContainer"></td>
  </tr>

在客户端 Java(到 JavaScript)中,它像这样访问 HTML 元素:

final Button sendButton = new Button("Send");
final TextBox nameField = new TextBox();
nameField.setText("GWT User");

我添加了一个容器字段以表明我可以使用 HTML 元素以编程方式添加一个链接:someStuffContainer。我还添加了另一个字段,通过调用 RPC 服务来填写注销 URL:logoutUrlContainer。 (是的,我知道现在有一种更简单的方法可以做到这一点:GWT/GAE(Java): when combined with GAE, app.yaml / web.xml user authentication and login/logout not really working。我只是想看看我是否可以让它工作。)请注意, someStuffContainer 只是为了使它成为一个受控实验:将通过使用在服务器端生成的注销链接填写该 URL 以编程方式添加 URL;这将在下面相关。

  <tr colspan="2">
    <td id="someStuffContainer"></td>
  </tr>
  <tr colspan="2">
    <td id="logoutUrlContainer"></td>
  </tr>

在客户端 Java(到 JavaScript)中,我这样做了:

// make it clear that we can add something to the page
final HTML someStuffHTML = new HTML
  ("<a href=https://www.google.com/search?q=zap>some stuff 3</a>");

// provide the user with a logout URL; FIX: do this by just
// providing a link to a generic logout servlet, rather than by
// proactively creating the logout link here.
final HTML userStatusHTML = new HTML();
GWT.log("userStatusService.getStatus()");
userStatusService.getStatus
  ("/", new AsyncCallback<UserStatusServiceResponse>() {

    public void onFailure(Throwable caught) {
      GWT.log("userStatusService.onFailure()");
      LogUtil.logThrowable(caught);
    }

    public void onSuccess(UserStatusServiceResponse result) {
      GWT.log("userStatusService.onSuccess()");
      if (result.loggedIn) {
        userStatusHTML.setHTML("<a href=\""+ result.logOutUrl+
                              "\">log out</a>");
      } else {
        // FIX: we should actually redirect to the base page
        userStatusHTML.setHTML("<a href=\""+ result.logInUrl+
                              "\">log in</a>");
      }
    }
  });

RootPanel.get("someStuffContainer").add(someStuffHTML);
RootPanel.get("logoutUrlContainer").add(userStatusHTML);

这一切都在程序化 HTML 显示并单击注销 url 将用户注销的意义上起作用。 (要查看这项工作,您必须在另一个选项卡中打开注销 url;如果您转到另一个页面,GWT devmode 插件会崩溃;它似乎进入了一种状态,它只是不断抱怨应用程序需要重新编译并您无法退出该状态。此外,您必须重新加载应用程序引擎才能要求您再次登录;如果您已注销并且客户端仍在运行,您可以继续使用该应用程序,除非打开您正在检查用户的服务器端是否已登录。)

在我看来,容器字段“logoutUrlContainer”的名称根本不重要。因此,在签入之前,我想我会清理代码并将其重命名为更通用的名称,这反映了我可能将该容器用于更通用的用户状态小部件的事实。所以我将“logoutUrlContainer”重命名为“userStatusContainer”;我在 .html 和客户端 Java(编译为 JavaScript)中重命名了它。现在,这一行得到了一个空指针异常,而不是工作:

RootPanel.get("logoutUrlContainer").add(userStatusHTML);

我是一位经验丰富的编码员:我确定要复制和粘贴以使字符串匹配。我检查了使用 emacs 中的搜索功能。我使用 ant clean 来清理整个项目。我使用 grep 对整个项目中可能被 ant clean 遗漏的任何二进制文件(例如类文件)进行 grep 处理,并且不知何故仍然包含旧名称。我重新启动了服务器,关闭了包含该应用程序的浏览器选项卡,等等。我重复所有这些。我反复得到空指针异常。我想我一遍又一遍地做了这一切至少一个小时。请注意, someStuffContainer 始终有效;不知何故 RootPanel.get() 总是找到它,而没有找到 userStatusContainer。最后,无奈之下,我只是重新命名了容器字符串。它立即起作用。我签到了。

这到底是怎么回事? ant clean 缺少什么吗?这是我自己扩展的 ant clean 目标:

  <target name="clean" description="Cleans this project">
    <delete  dir="gwt-unitCache" failonerror="false" />
    <delete  dir="war/myapp" failonerror="false" />
    <delete  dir="war/WEB-INF/classes" failonerror="false" />
    <delete  dir="war/WEB-INF/lib" failonerror="false" />
    <delete  dir="war/WEB-INF/deploy" failonerror="false" />
    <delete file="war/WEB-INF/appengine-web.xml" failonerror="false" />
    <delete file="war/WEB-INF/web.xml" failonerror="false" />
  </target>

我没有删除所有 war/WEB-INF 的唯一原因是我使用可选的 app.yaml 来配置 Java Google App Engine,而不是自己编辑 .xml 文件。

我的 ant clean 目标是否遗漏了什么?这种体验真的让我不想用GWT了。


更新:我想我知道发生了什么:javascript 正在重新编译,但我从未想过 GWT 开发插件会允许缓存页面。后来我更改了欢迎文件列表,旧的欢迎文件仍在显示。研究配置文件,我想不出任何可能的方法。最后我只是点击重新加载并显示新文件。

无论如何,缓存可以解释这个问题中报告的错误。我不知道 GWT 正在做什么以允许缓存页面,尤其是在开发模式下。你认为在做了 15 年的网络开发人员之后,我可能更早地想到了这一点。但是我无法想象人们怎么可能对缓存效果如此草率,尤其是在开发框架中。


我正在运行最新版本的 OS X 10.6.8 (x86)。 我的浏览器是 Chrome:16.0.912.63(官方版本 113337) $ java -版本 java版本“1.6.0_29” Java(TM) SE 运行时环境 (build 1.6.0_29-b11-402-10M3527) Java HotSpot(TM) 64 位服务器 VM(内部版本 20.4-b02-402,混合模式) 我正在使用 gwt-2.4.0。

【问题讨论】:

    标签: java google-app-engine gwt ant


    【解决方案1】:

    它似乎进入了一种状态,它只是不断抱怨应用程序需要重新编译,而你无法摆脱这种状态

    这与您正在调试的事实有关,因此开发模式用更新版本覆盖了一些已编译的文件,并且当您没有重新编译(并且启动应用程序不是在开发模式下)时,它会注意到丢失文件和停止。如果要使用开发模式,请将?gwt.codesvr=... 附加到新页面的 url,它也会以开发模式运行该页面。或者编译应用程序,不要使用任何具有开发模式的页面(加载该模块 - 其他模块都可以)。

    我怀疑如果您将该后缀添加到 url,您的整个问题将消失 - 如果 RootPanel.get("some-id") 与 html 页面不匹配,您看到的 NPE 是由于 RootPanel.get 返回 null 和 add在 null 上被调用。

    【讨论】:

      猜你喜欢
      • 2023-03-18
      • 1970-01-01
      • 2016-09-18
      • 2023-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-11
      相关资源
      最近更新 更多