GWT: как разделить объект Java (например, EventBus) между двумя модулями

Я создаю большое приложение, и я хотел бы разделить его на несколько модулей, таких как основной модуль для инициализации, управления пользователями и т. д., клиентский модуль, производственный модуль и т. д.

Я хочу разделить его на несколько модулей GWT (без использования техники разделения GWT) и поделиться EventBus для трансляции некоторых событий, таких как LoginEvent, LogoutEvent. Я не хочу использовать метод разделения кода, потому что я хочу сократить время компиляции и перекомпилировать только тот модуль, который я изменил. Это позволяет также включать или отключать модуль, комментируя тег script на главной странице HTML.

Я написал следующий код с использованием JSNI:

CoreModule’s EntryPoint:

private static SimpleEventBus eventBus = null;

public void onModuleLoad() {
    export();
    getEventBus().addHandler(MyEvent.TYPE, new MyEventHandler() {

        @Override
        public void onEvent(MyEvent myEvent) {
            Window.alert(myEvent.getMessage());
        }
    });
}

public static SimpleEventBus getEventBus() {
    if (eventBus == null)
        eventBus = new SimpleEventBus();
    return eventBus;
}

public static native void export() /*-{
    $wnd.getEventBus = $entry(@testExporter.client.TestExporter::getEventBus());
}-*/;

CustomerModule’s EntryPoint:

public void onModuleLoad() {
    Button button = new Button("Click me");
    button.addClickHandler(new ClickHandler() {

        @Override
        public void onClick(ClickEvent event) {
            getEventBus().fireEvent(new MyEvent("Button clicked !"));
        }
    });
    RootPanel.get().add(button);
}

public static native SimpleEventBus getEventBus() /*-{
    // Create a useless eventBus because the GWT compiler make a call to a null instance
    var eventBus = @com.google.gwt.event.shared.SimpleEventBus::new()();
    eventBus = $wnd.getEventBus();
    return eventBus;
}-*/;

Но у меня есть следующее исключение в Firebug при выполнении в браузере:

uncaugth exception [object Object]

Я также скопировал классы MyEvent и MyEventHandler, которые реализуют/взаимодействуют с клиентским событием.

P.S.: Я также знаю технику, заключающуюся в том, чтобы комментировать ссылки на другие модули, чтобы избежать их компиляции.


person Justin C.    schedule 24.03.2013    source источник


Ответы (3)


Более простой ответ — не использовать несколько точек входа.

==========================================

Если вы пытаетесь разбить свой код на управляемые блоки, но хотите использовать их все на одной странице, вы можете:

  • создайте модуль "Application.gwt.xml" с точкой входа (эквивалент вашего модуля инициализации, если я правильно понимаю)
  • создать модуль "UserManagement.gwt.xml" без класса точки входа
  • создавать другие модули XXX без точек входа

Чтобы создать модуль без точки входа, просто удалите

<entry-point class='xxx'/>

из ваших файлов gwt.xml, кроме файла "Приложение"

Затем вам нужно включить эти модули в модуль «Приложение», используя

<inherits name="com.yourpackage.Module1Name" />
<inherits name="com.yourpackage.Module2Name" />

Затем вам нужно скомпилировать их все вместе в одну сборку GWT для модуля «com.yourpackage.Application».

Когда вы это сделаете, убедитесь, что скомпилированные файлы *.class и исходные файлы .java для всех ваших модулей доступны в пути к классам.

Ваша точка входа «Приложение» просто должна инициализировать и использовать объекты из других модулей.

person gbazin    schedule 27.03.2013

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

Но имейте в виду, что: во-первых, общие классы будут несовместимы, потому что каждая компиляция будет переименовывать классы/методы по-разному, а во-вторых, каждая компиляция будет удалять разные мертвые фрагменты кода.

Таким образом, в вашем случае SimpleEventBus, возвращаемый в вашем экспортированном методе window.getEventBus, не известен в других модулях, хотя другие модули также используют SimpleEventBus

Самый простой способ сделать то, что вы хотите, — использовать GWT-exporter. Сначала правильно выберите js-api, который вы хотите экспортировать в каждом модуле, как вы хотите его назвать, и удобно реализовать Exportable и аннотировать методы. Во-вторых, примите во внимание, какие объекты вы будете использовать для общения, потому что некоторые из них могут быть несовместимы. Я бы использовал примитивные типы, объект javascript и функции, которые поддерживаются в GWT-exporter.

Я думаю, что с помощью GWT-exporter для общих классов, если вы аннотируете их в одном и том же пространстве имен и экспортируете одни и те же методы, надеюсь, вы сможете использовать их во всех модулях, но я не уверен.

Поэтому экспортируйте js API через jsni или gwt-exporter и передавайте между ними чистые примитивы или js-объекты.

person Manolo Carrasco Moñino    schedule 25.03.2013

Вы можете использовать фреймы и настроить связь между модулями по протоколу WebMessage. Поможет только если модули на одной странице а модули в разных войнах.

person formatqs    schedule 17.09.2014