Как разделить ресурсы данных между виджетами в GWT

Я использую GWT и AppEngine для проекта. Я хотел бы знать, как я могу обмениваться данными (объектами ArrayList) между виджетами, чтобы я мог централизовать логику и уменьшить количество вызовов RPC к серверу.

Я думал о двух способах, но я не знаю, что лучше:

1) Когда я создаю экземпляр виджета, я передаю объект ArrayList в качестве параметра, хотя я не знаю, как это сделать, потому что экземпляр виджета создается с помощью:

  ThisAppShell shell = GWT.create(ThisAppShell.class);    

2) Используя механизм вроде EventBus

http://www.dev-articles.com/article/Gwt-EventBus-(HandlerManager)-the-easy-way-396001

Когда пользователь загружает приложение, после завершения процесса входа в систему я хотел бы загрузить список сотрудников, который должен быть доступен для всех виджетов. Все это должно быть сделано в методе onModuleLoad(). Я хотел бы загрузить их все при запуске, потому что я хотел бы реализовать какой-то механизм кэширования. Например, я хочу иметь 2 экземпляра ArrayList: - emplListOnStart, который заполняется при загрузке приложения - emplListChanges - массив, в который пользователь будет вносить изменения из виджетов.

После того, как пользователь закончил вносить изменения (он нажимает кнопку "Сохранить"), два массива будут сравнены, различия будут сохранены в appengine (через RPC), а также обновлены в emplListOnStart.

Это код для класса EntryPoint:

public class ThisApp implements EntryPoint {
ThisAppShell shell = GWT.create(ThisAppShell.class);
LoginServiceAsync loginService = GWT.create(LoginService.class);

private ArrayList<Employee> emplListOnStart;

private ArrayList<Employee> emplListChanges;

public void onModuleLoad() {
    RootLayoutPanel.get().clear();
    RootLayoutPanel.get().add(shell);
    loginService.isAuthenticated(new AsyncCallback<UserDto>() {

        public void onFailure(Throwable caught) {
            // TODO Auto-generated method stub

        }

        public void onSuccess(UserDto result) {
                             //Here I should load the emplListOnStart list;
        }

    });
    shell.getLogoutLink().addClickHandler(new ClickHandler() {
        public void onClick(ClickEvent event) {
            loginService.logout(new AsyncCallback() {
                public void onFailure(Throwable caught) {

                }

                public void onSuccess(Object result) {
                                             //Here the user will get logged out
                }
            });
            Window.Location.assign("");
        }
    });

   }
}

А вот код для виджета:

public class ThisAppShell extends Composite {

private static ThisAppShellUiBinder uiBinder = GWT
        .create(ThisAppShellUiBinder.class);

interface ThisAppShellUiBinder extends UiBinder<Widget, ThisAppShell> {
}

@UiField
Anchor logout_link;
@UiField
StackLayoutPanel stackLPanel;
@UiField
TabLayoutPanel tabLPanel;

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

    initializeWidget();
}

public void initializeWidget() {
    stackLPanel.add(new HTML("Manage empl."), new HTML("Employees"), 30);
    stackLPanel.add(new HTML("Manage Dept."), new HTML("Departments"), 30);

    // Add a home tab
    HTML homeText = new HTML("This is the home tab");
    tabLPanel.add(homeText, "Home");

    // Add a tab
    HTML moreInfo = new HTML("This is the more info tab");
    tabLPanel.add(moreInfo, "More info");

    // Return the content
    tabLPanel.selectTab(0);
}

public Anchor getLogoutLink() {
    return logout_link;
}

}

Возможно ли это, или как это можно сделать лучше?

Спасибо.

1 ответ

Решение

Я думаю, что есть два способа сделать это:

  1. Создайте сеттер на вашем виджете, чтобы установить ваши экземпляры ArrayList (setData()). Затем вы можете вызвать эту функцию в onSuccess метод вашего входа в систему.

  2. Внедрить единичный экземпляр глобального EventBus в ваш виджет (используя то есть gin/guice) и запустите событие, содержащее ваши данные. В виджете вы должны прикрепить EventHandler для конкретного события (т.е. LoadEmplListEvent).

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

Решение - более чистый подход, потому что оно отделяет ваши виджеты от остальных. Вы запускаете событие данные в вашем onSuccess метод один раз, и вы не заботитесь о виджетах.
Виджеты, которые заинтересованы в данных, будут следить за тем, чтобы они правильно обрабатывали событие (обрабатывая событие). Я думаю, если у вас есть много виджетов, которые имеют дело с данными, второй подход - это тот, который нужно использовать.

Другие вопросы по тегам