Как я могу использовать RequestFactory для создания объекта и инициализации коллекции внутри него объектами, полученными из другого ReqFactory? - PullRequest
0 голосов
/ 26 июня 2011

Я борюсь с проблемой использования RequestFactory в GWT. У меня есть объект User: этот объект имеет поля логина и пароля, а также другие поля типа коллекции.

public class User {
    private String login;
    private String password;
    private Set<Ressource> ressources;

    // Getters and setters removed for brievety
} 

Мне нужно сохранить этот объект в БД, поэтому я использовал RequestFactory, потому что для меня это похоже на операцию типа CRUD.

Теперь для части кода RequestFactory, вот как я пытался это сделать:

  1. Я создаю объект UserRequestContext для создания объекта запроса для нового пользователя. Что дает что-то вроде:

    public interface MyRequestFactory extends RequestFactory {
        UserRequestContext userRequestContext();
        RessourceRequestContext ressourceRequestContext();
    }
    

    и для создания объекта пользователя у меня есть что-то вроде этого:

    public class UserAddScreen extends Composite {
        private UserProxy userProxy;
        EventBus eventBus = new SimpleEventBus();
        MyRequestFactory requestFactory = GWT.create(MyRequestFactory.class);
        ...
    
        public UserAddScreen() {
            ...
            requestFactory.initialize(eventBus);
        }
    
        public showUserAddScreen() {
            // Textbox for password and login
            // Listbox for ressources
        }
    
    }
    

Я пытался реализовать его как мастера. Так что в начале UserAddScreen у меня есть объект userProxy. Поля этого объекта инициализируются на каждом шаге мастера:

  • первый шаг - добавление логина и пароля
  • второй шаг - добавление ресурсов к объекту userProxy.

для этого последнего шага у меня есть два списка, в первом из которых содержится список всех ресурсов, которые есть в моей таблице БД. Ресурсы, которые я получил от RessourceRequestContext.getAllRessource (у меня есть цикл для отображения их как элемента списка с RessourceId в качестве значения), а второй позволяет мне добавить выбранные Ressources из этого первого списка. Вот первый список:

    final ListBox userRessourcesListBox = new ListBox(true);
    Receiver<List<RessourceProxy>> receiver = new Receiver<List<RessourceProxy>>() {

        @Override
        public void onSuccess(List<RessourceProxy> response) {
            for(RessourceProxy ressourceProxy : response) {
                ressourcesListBox.addItem(ressourceProxy.getNom() + " " + ressourceProxy.getPrenom(), String.valueOf(ressourceProxy.getId()));
            }
        }
    };
    RessourceRequestContext request = requestFactory.ressourceRequestContext();
    request.getAllRessource().fire(receiver);

Итак, как вы можете видеть, мой код перебирает извлеченные прокси из БД и инициализирует элементы в списке.

Вот кнопки управления:

final Button addButton = new Button(">");
    addButton.addClickHandler(new ClickHandler() {

        public void onClick(ClickEvent event) {
            for (int i = 0; i < ressourcesListBox.getItemCount(); i++) {
                boolean foundInUserRessources = false;
                if (ressourcesListBox.isItemSelected(i)) {
                    for (int j = 0; j < userRessourcesListBox
                            .getItemCount(); j++) {
                        if (ressourcesListBox.getValue(i).equals(
                                userRessourcesListBox.getValue(j)))
                            foundInUserRessources = true;
                    }

                    if (foundInUserRessources == false)
                        userRessourcesListBox.addItem(ressourcesListBox
                                .getItemText(i), ressourcesListBox
                                .getValue(i));
                }
            }
        }
    });

Таким образом, когда кто-то выбирает одного или нескольких пользователей и нажимает кнопку «>», все выбранные элементы переходят во второй список, который называется userRessourceListBox

userRessourcesListBox.setWidth("350px");
    userRessourcesListBox.setHeight("180px");

После этого у меня есть кнопка FINISH, которая зацикливается на элементах во втором списке (которые я выбрал из первого), и я пытаюсь сделать запрос (снова) с RequestFactory для получения ressourceProxy объект и инициализировать коллекцию ресурсов userProxy с результатом

final Button nextButton = new Button("Finish");

    nextButton.addClickHandler(new ClickHandler() {

        public void onClick(ClickEvent event) {
            RessourceRequestContext request = requestFactory.ressourceRequestContext();
            for(int i = 0; i < userRessourcesListBox.getItemCount(); i++) {
                Receiver<RessourceProxy> receiver = new Receiver<RessourceProxy>() {
                    @Override
                    public void onSuccess(RessourceProxy response) {
                        userProxy.getRessource().add(response);
                    }
                };
                request.find(Long.parseLong(userRessourcesListBox.getValue(i))).fire(receiver);
            }
              creationRequest.save(newUserProxy).fire(new Receiver<Void>() {

                @Override
                public void onSuccess(Void response) {
                    Window.alert("Saved");
                }
            });
        }

    });

Наконец, (в коде выше) я пытаюсь сохранить объект UserProxy (с начальным контекстом запроса, с которым я создал userProxy) ... но он не работает

creationRequest.save(newUserProxy).fire(...)

Похоже, что зацикливание результата в методе onSuccess:

userProxy.getRessource().add(response);

Я получаю ответ (типа RessourceProxy), но за пределами этого метода, например, когда я пытаюсь сохранить объект userProxy ПОСЛЕ ЦИКЛА, в коллекции ressourceProxy userProxy нет объектов RessourceProxy ...

Ребята, вы когда-нибудь испытывали что-то подобное? Возможно, я не делаю это правильно: мне нужно получить ресурс с UserRequestContext? чтобы мой объект newUser и ресурсы управлялись одним и тем же контекстом запроса? если да, то я думаю, что это немного странно - смешивать что-то вместе: я имею в виду, какая польза от операции, связанной с Ressource, в контексте запроса, связанного с пользователем.

любая помощь была бы действительно очень ... и я имею в виду очень признателен ;-) Большое спасибо

1 Ответ

0 голосов
/ 27 июня 2011

Сообщение «… было заморожено» означает, что объект был либо edit() отредактирован, либо передан в качестве аргумента методу сервиса, в другом экземпляре RequestContext (не имеет значения, принадлежит ли он к тому же -type -ie UserRequestContext против RessourceRequestContext - или нет), который еще не был fire() d и / или ответ еще не вернулся с сервера (или вернулся с нарушениями: когда получатель получил onViolation вызывается, объекты все еще доступны для редактирования, в отличие от onSuccess и onFailure).

ОБНОВЛЕНИЕ : у вас есть условие гонки: вы перебираете идентификаторы ресурса и порождаете столько запросов, сколько элементов выбрано пользователем, а затем, не дожидаясь их ответа (помните: это все асинхронно), вы сохраняете пользовательский прокси. Как только вы fire() этот последний запрос, пользовательский прокси больше не является изменяемым (т.е. заморожен).

IMO, лучше сначала сохранить извлеченные RessourceProxy и использовать их непосредственно в прокси-сервере пользователя перед его сохранением (т. Е. Запрос find() в фазе "финиш" не требуется). Поместите их в карту по идентификатору и получите их с карты вместо find повторного извлечения их с сервера.

...