Привязка данных к пользовательскому интерфейсу в GWT - PullRequest
0 голосов
/ 16 июня 2011

В Silverlight часто используется шаблон:

  1. Данные запроса
  2. Возвращение пустого контейнера для данных
  3. Асинхронный запуск запроса на заполнениеконтейнер
  4. Когда запрос вернется, вызовите событие для контейнера
  5. Обновите интерфейс в соответствии с содержимым контейнера

Можно ли это сделать в GWT?

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

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

Каков здесь правильный подход?

1 Ответ

3 голосов
/ 16 июня 2011

Предположим, вы используете GWT RPC.У вас будет некоторый сервисный интерфейс, который позволяет вам выбирать групповые идентификаторы для предложения и значок для конкретного идентификатора группы.

public interface FacebookService extends RemoteService {

    List<String> getFacebookGroupIds(String suggestion);

    Icon getIconForGroup(String groupId);
}

Вы должны создать свою собственную реализацию Предложения, которая может отображать себя с помощью всего лишьgroupId или groupId и Icon.

public class FacebookGroupSuggestion implements Suggestion {

    private String groupId;

    private Icon icon;

    public FacebookGroupSuggestion(String groupId) {
        this.groupId = groupId;
    }

    public String getDisplayString() {
        StringBuilder builder = new StringBuilder();
        builder.append("<b>");
        builder.append(this.groupId);
        builder.append("</b>");
        if (this.icon != null) {
            builder.append(this.icon.toSafeHtml());
        }
        return builder.toString();
    }
}

Я использую Icon как собственную реализацию значка, это не стандартный класс.Затем вы можете сделать свою реализацию SuggestOracle для асинхронной выборки идентификаторов групп и значков.SuggestOracle использует функцию обратного вызова для информирования offerBox о наличии ответа на запрос.Так что принесите свои результаты и перезвоните, когда получите их.Это будет выглядеть примерно так.

public class FacebookSuggestOracle extends SuggestOracle {

    private FacebookServiceAsync service = GWT.create(FacebookService.class);
    private Request currentRequest;
    private Callback currentCallback;

    @Override
    public void requestSuggestions(Request request, Callback callback) {
        // Save request & callback for future use.
        this.currentRequest = request;
        this.currentCallback = callback;

        // Fetch the groupIds
        service.getFacebookGroupIds(request.getQuery(), new AsyncCallback<List<String>>() {
            public void onSuccess(List<String> result) {
                createSuggestionsForGroupIds(result);
            }

        });

    }

    private void createSuggestionsForGroupIds(List<String> groupIds) {
        List<FacebookGroupSuggestion> suggestions = new ArrayList<FacebookGroupSuggestion>();
        for (String groupId : groupIds) {
            suggestions.add(new FacebookGroupSuggestion(groupId));
        }
        Response response = new Response(suggestions);
        // Tell the suggestBox to display some new suggestions
        currentCallback.onSuggestionsReady(currentRequest, response);

        // Fetch the icons
        for (String groupId : groupIds) {
            service.getIconForGroup(groupId, new AsyncCallback<Icon>() {

                public void onSuccess(Icon result) {
                    // match the icon to the groupId in the suggestion list
                    // use the callback again to tell the display to update itself

                }

            });
        }
    }
}
...