Какое значение может иметь имя идентификатора тега контейнера? - PullRequest
0 голосов
/ 16 января 2012

Я пишу приложение GWT / GAE (Java). Пример автоматически созданного слова приветствия, который поставляется с GWT, генерирует код, подобный следующему:

<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): в сочетании с GAE аутентификация пользователя app.yaml / web.xml и вход в систему / выход из системы на самом деле не работают . Я просто хотел посмотреть, смогу ли я заставить его работать.) Обратите внимание, что 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 выхода из системы на другой вкладке; плагин devmode GWT выходит из себя, если вы переходите на другую страницу; похоже, он попадает в состояние, в котором он просто продолжает жаловаться, что приложение нужно перекомпилировать и Вы не можете выйти из этого состояния. Кроме того, вы должны нажать перезагрузить для ядра приложения, чтобы потребовать повторного входа в систему, если вы вышли из системы, а клиентская сторона все еще работает, вы можете просто продолжать использовать приложение, если не на стороне сервера, которую вы проверяете, пользователь вошел в систему.)

Мне кажется, что имя поля контейнера "logoutUrlContainer" вообще не должно иметь значения. Поэтому, прежде чем регистрироваться, я решил очистить код и переименовать его в нечто более общее, отражающее тот факт, что я мог бы использовать этот контейнер для более общего виджета «Статус пользователя». Поэтому я переименовал «logoutUrlContainer» в «userStatusContainer»; Я переименовал его в .html и в клиентскую Java (скомпилировано в JavaScript). Теперь вместо работы эта строка получает исключение нулевого указателя:

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

Я довольно опытный программист: я был уверен, что скопировал и вставил, чтобы строки соответствовали. Я проверил, используя функцию поиска в Emacs. Я использовал ant clean для очистки всего проекта. Я использовал grep для grep для любых двоичных файлов (таких как файлы классов) во всем проекте, которые могли быть пропущены ant clean и каким-то образом все еще содержали старое имя. Я перезапустил сервер, убил вкладку браузера, содержащую приложение и т. Д. Я делал все это неоднократно. Неоднократно я получаю исключение нулевого указателя. Я думаю, что делал все это снова и снова, по крайней мере, в течение часа. Обратите внимание, что все время someStuffContainer всегда работал; каким-то образом RootPanel.get () всегда находил его, не находя userStatusContainer. Наконец, в отчаянии я просто снова назвал строку контейнера. Сразу это работает. Я зарегистрировался.

Что, черт возьми, происходит? Муравей чистым что-то упустил? Вот моя мишень для чистой муравьи, которую я расширил сам:

  <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 самостоятельно.

Неужели в моей цели нет муравьев? Этот опыт действительно заставляет меня не хотеть использовать GWT.


Обновление : Мне кажется, я знаю, что случилось: javascript перекомпилировался, но мне никогда не приходило в голову, что плагин разработки GWT позволит кэшировать страницу. Позже я изменил список файлов приветствия, и старый файл приветствия все еще отображался. Изучая файлы конфигурации, я не мог придумать, как это было бы возможно. Наконец я просто нажал перезагрузить и новый файл отобразился.

В любом случае, кэширование объяснит ошибку, о которой сообщается в этом вопросе. Я не знаю, что делает GWT, позволяя кэшировать страницу, особенно в devmode. Вы думаете, что после 15 лет веб-разработки я мог подумать об этом раньше. Однако я не могу представить, как люди могут быть настолько небрежными с эффектами кэширования, особенно в средах разработки.


Я использую последнюю версию OS X 10.6.8 (x86). Мой браузер Chrome: 16.0.912.63 (Официальная сборка 113337) $ java-версия Java-версия "1.6.0_29" Java (TM) SE Runtime Environment (сборка 1.6.0_29-b11-402-10M3527) Java HotSpot (TM) 64-разрядная серверная виртуальная машина (сборка 20.4-b02-402, смешанный режим) Я использую gwt-2.4.0.

1 Ответ

0 голосов
/ 16 января 2012

кажется, что он приходит в состояние, в котором он просто продолжает жаловаться, что приложение нужно перекомпилировать, и вы не можете выйти из этого состояния

Это связано с тем, чточто вы отлаживали, поэтому режим Dev перезаписал некоторые скомпилированные файлы с обновленными версиями, а когда вы не перекомпилировали (и запускаете приложение не в режиме dev), он замечает отсутствующие файлы и останавливается.Если вы хотите использовать режим dev, добавьте ?gwt.codesvr=... к URL новой страницы, и она также будет запускать эту страницу в режиме dev.Или скомпилируйте приложение и не используйте никакие страницы с режимом разработки (загрузка этого модуля - другие модули в порядке).

Я подозреваю, что если вы добавите этот суффикс в URL, вся ваша проблема исчезнет -NPE, который вы видите, если RootPanel.get("some-id") не соответствует html-странице, это из-за того, что RootPanel.get возвращает ноль и add вызывается с нулем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...