Пишем сайт на GWT: Часть 1

в 12:56, , рубрики: Google, Google Web Toolkit, GWT, javascript, Веб-разработка, метки: , ,

Добрый день дамы и господа,

На хабре есть не так много статей на тему GWT (Google Web Toolkit) и в большинстве своем написаны они в ключе «какая это бяка, ничего не умеет, ничего не понятно». Кроме того, как показывает мой опыт, большинство программистов о GWT вообще ничего не слышали, а те кто слышал, думают, что больше чем на „Hello World“он не способен. Я постараюсь показать вам, что с помощью этого замечательного Фреймворка можно делать такие вещи, которые большинству JavaScript программистам просто не по зубам.

Перед началом небольшое отступление, т.к. вопрос «а зачем?» обязательно прозвучит. Этот сайт я написал на GWT, т.к. у меня и выбора то не было. С HTML,CSS, PHP и JavaScriptом я знаком(был) весьма поверхностно( как собственно и большинство Java-программистов), а вот идея и желание были. А потому использовал я что имел и получилось вроде весьма не плохо.

Посмотрите на этот сайт. Да это не шедевр, но он показывает, что GWT может все, что может JavaScript и даже больше. Почему больше? Ответ на этот вопрос полностью совпадает с ответом на вопрос: «почему С++ может больше чем Assembler?». На эту тему я предлагаю подискутировать в комментариях. А мы возвращаемся к GWT. Нет ничего лучше( мое стойкое убеждение), чем объяснять что либо на примере, а посему я предлагаю вам препарировать этот сайт.

image

Итак, начали

Вешаем слушателей на элементы

Итак, любое GWT приложение состоит из как минимум одной HTML-страницы и кучи яваскриптов. Посмотрим на эту самую страничку. Как не сложно догадаться, все самое интересное будет происходить в диве „ content“. Весь хедер и футер сделаны хардкорно, т.е. статически, и по существу к GWT никакого отношения не имеют(выключите JavaScript и поймете о чем я ). Но вот клики на кнопки обрабатывает GWT. Как это сделано? На каждый див(кнопку) вешается слушатель:

final Element element = DOM.getElementById("homeSite");
DOM.sinkEvents(element, Event.ONCLICK);
DOM.setEventListener(element, new EventListener() {
public void onBrowserEvent(Event event) {
if (DOM.eventGetType(event) == Event.ONCLICK) {
// наша логика
}
}
});

Вот и все, вот так просто. Я думаю в этом коде все понятно, может быть только за исключением строки:

DOM.sinkEvents(element, Event.ONCLICK);

Эта строка обязательна, т.к. говорит браузеру, что с этого момента этот элемент реагирует на клик. Если эту строку выкинуть, то слушатель сигнала о событии не получит и ваша логика, соответственно, обработана не будет. Эту мелочь надо просто знать, как собственно, везде и всегда.

Загрузка статического HTML-файла.

Но не весь контент генерируется на лету. Например центральная страница, это статический HTML. Как это так? Фаербаг вам это подтвердит. Он вам покажет, что на центральной странице грузится startRu.html (или startDE.html, если браузер сказал, что его родной язык- немецкий). Как это сделано?

RequestBuilder requestBuilder = new RequestBuilder(RequestBuilder.GET, GWT.getHostPageBaseURL() + "start/start" + language.getAbkurzung() + ".html");
try {
requestBuilder.sendRequest(null, new RequestCallback() {

public void onResponseReceived(Request request, Response response) {

if (response.getStatusCode() != 200) {
Window.alert(language.geЕrror() + "!");
} else {
HTML startHTML = new HTML(response.getText());
RootPanel.get(„content“).getElement().setInnerHTML("");
RootPanel.get(„content“).add(startHTML);
}
}

public void onError(Request request, Throwable exception) {
Window.alert(language.getError() + "!");
}
});
} catch (RequestException ex) {
Window.alert(language.getError() + "!");
}
}

Некоторые могут сказать «многа букaфф» и я с ними соглашусь. Но с другой стороны каждая строчка предельно ясна и этот код позволяет реагировать на ошибки. После загрузки этой страницы необходимо инициализировать ссылки(Выбрать модель, Положить в корзину и.д.). Инициализация, как вы догадываетесь, происходит точно так же как и у дивов.

Переход между страницами

Обратите внимание как происходит переход между страницами. Старый контент медленно исчезает, а новый так же медленно появляется. Кому то этот эффект может не понравиться и поэтому я просто посмотрел, какое впечатление произведет сайт, если этот эффект отключить. На вкус и цвет, как известно фломастеры разные, но мне на сайт без этого эффекта смотреть было уже не приятно. Итак, как это сделано. В GWT есть класс Animation. Посмотрите примеры в интернете, т.к. код для статьи слишком громоздкий. Но идея в общем такова: я написал класс, который получает получает ссылку на виджет, который должен появится. Ссылка на актуальный виджет, который отображается в данный момент, хранится в статическом поле центрального класса, который выполняет роль склада(паттерн registry). У старого виджета медленно изменяется свойство Opacity с 1 до 0, потом старый виджет заменяется на новый и у него меняем свойство Opacity с 0 до 1. Замена виджетов происходит очень просто:

oldWidget.removeFromParent();
RootPanel.get(„content“).add(newWidget);

По этому же принципу появляются все Pop-Upы.

Я думаю для начала хватит.

На этой странице много чего интересного, например сайт запоминает установленный язык, работают кнопки вперед-назад, динамический перевод сайта с русского на немецкий и наоборот(перевод, кстати, при загрузке сайта происходит до того, как вы увидите страницу), один раз подгруженная страница кэшируется(посмотрите, подгружается ли повторно например startRu.html?). Когда вы наведете на маленькие иконки продукта в таблице «купленных» продуктов, вы увидите один маленький фокус. Мелочь, а приятно. Красивые тултипы, которые показывают ошибки при регистрации. Проверка полей на клиенте. Поля, которые принимают только цифры и много чего еще.Попробуйте «купить» один продукт, получите ссылку и посмотрите, что происходит. А вам интересно КАК это происходит?

И все это сделал человек, который не имеет(вернее не имел) практически ни малейшего понятия о HTML,CSS и JavaScript в свободное от работы/учебы/жены/детей время и успевал еще и пиво с друзьями попивать!

Задавайте вопросы, если вам интересно как та или иная фича реализована.

История о том, как я этот сервис пытался продвигать, тоже, кстати, весьма интересна.

А теперь я вам открою истинную цель этого топика. Я ищу людей/инвесторов/компаньонов для этого проекта. Любые идеи, пожелания, конструктивная критика приветствуются.

Автор: schroeder

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js