RequestFactoryEditorDriver получает отредактированные данные после сброса

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

У меня EntityProxy отображается на панели просмотра. Панель представления - это RequestFactoryEditorDriver, только использующий режим отображения. Пользователь нажимает на элемент данных и открывает всплывающий редактор, чтобы редактировать элемент данных EntityProxy с несколькими битами данных, которые отображаются на панели просмотра. Когда пользователь сохраняет элемент, мне нужна панель просмотра, чтобы обновить отображение.

Я столкнулся с проблемой, потому что RequestFactoryEditorDriver потока всплывающего редактора не позволяет вам получить доступ к отредактированным данным. Драйвер использует тот же передаваемый в контексте, что вы используете для отправки данных на сервер, однако контекст, возвращаемый из сброса, позволяет только Receiver<Void> даже если вы приведете его к типу контекста, который вы сохранили в драйвере редактора при вызове edit(). [ Похоже, что оно не отправляет и событие EntityProxyChanged, поэтому я не смог прослушать это и обновить представление дисплея. - поцарапать это - я вижу, теперь это событие не для этого варианта использования ]

Решение, которое я нашел, состояло в том, чтобы изменить мой объект доменного имени, чтобы вернуть вновь сохраненную сущность Затем создайте всплывающий редактор, как это

editor.getSaveButtonClickHandler().addClickHandler(createSaveHandler(driver, editor));
                // initialize the Driver and edit the given text.
                driver.initialize(rf, editor);
                PlayerProfileCtx ctx = rf.playerProfile();
                ctx.persist().using(playerProfile).with(driver.getPaths())                      
                        .to(new Receiver<PlayerProfileProxy>(){
                    @Override
                    public void onSuccess(PlayerProfileProxy profile) {
                        editor.hide();
                        playerProfile = profile;
                        viewDriver.display(playerProfile);
                    }                               
                });
                driver.edit(playerProfile, ctx);
                editor.centerAndShow();

Затем в обработчике сохранения я просто запускаю () контекст, полученный из flush(). Хотя этот подход работает, он не кажется правильным. [ Казалось бы, я должен подписаться на событиеменимый объект в представлении отображения и обновить сущность и представление оттуда. - еще раз, та же причина, что и раньше ] Также этот подход сохраняет весь объект, а не только измененные биты, что увеличит использование полосы пропускания.

Я думаю, что должно произойти, когда вы очищаете сущность, она должна "оптимистично" обновить управляемую RF-версию этой сущности и запустить событие изменения прокси-объекта сущности. Только возвращение объекта, если что-то пошло не так в сохранении. Фактическое сохранение должно отправлять только измененные биты. Таким образом, нет необходимости повторно извлекать всю сущность и дважды передавать эти полные данные по сети.

Есть ли лучшее решение?

2 ответа

Решение

Я нашел лучшее решение. Я делаю прокси редактируемым перед вызовом editFactoryEditorDriver edit() и сохраняю редактируемый прокси как мой прокси просмотра.

PlayerProfileCtx ctx = rf.playerProfile();
playerProfile = ctx.edit(playerProfile);
driver.edit(playerProfile, ctx);

Кроме того (и я думал, что пробовал это раньше, и это не сработало, но я, должно быть, тогда сделал что-то не так), я могу разыграть контекст, который возвращается из флеша. Это тот же контекст, который я отправил водителю с edit() звоните, так что это безопасно.

PlayerProfileCtx ctx  = (PlayerProfileCtx) driver.flush();

Это исправило проблему с отправкой rf всего объекта с помощью fire(), а не только различий. Я не уверен, почему, хотя. Это может быть ошибка в драйвере редактора RF.

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

Похоже, вы не совсем понимаете детали того, что происходит с РФ; Кроме того, ваша терминология не очень помогает в понимании (флеш против огня).

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

EntityProxyChange событие отправляется на стороне клиента (для объекта, который уже известен серверу и был отправлен с клиента), когда сервер обнаружил, что он изменился: либо его версия (как возвращено getVersion на Locator) был изменен или был удален (как сказано isLive метод Locator). Если вы не используете Locator Буду использовать getVersion сущности и isLive будет заменен на find с использованием объекта по его идентификатору (как getId метод) и проверка на null (это также реализация по умолчанию isLive в Locator).
В вашем случае, если вы не видите EntityProxyChange будучи отправленным, проверьте, правильно ли вы обновили версию сущности.

Наконец, RF всегда отправляет различия ваших изменений на сервер (за исключением ValueProxy, в этом случае diff не будет иметь никакого значения). Что касается извлечения данных, то он не извлекает связанные прокси по умолчанию, если вы явно не запросите их, используя with; и это не зависит от того, что вы, возможно, отправили о сущности.

В вашем случае, чтобы обновить панель просмотра, у вас есть 3 возможности:

  • получить прокси обратно с сервера (прослушивание EntityProxyChange события или после явного сигнала из вашего всплывающего окна; Вы могли бы использовать find метод RequestContext с прокси stableId в качестве аргумента и соответствующего with для свойств, которые вам нужны).
    Это немного неэффективно, так как вы делаете второй HTTP-запрос, но, с другой стороны, он может обрабатывать изменения из любого места в вашем приложении (они будут запускаться EntityProxyChange события тоже)
  • получить обновленный прокси в том же HTTP-запросе, который вы используете для его сохранения: save Метод вашего контекста запроса возвращает сохраненную сущность или вызывает find метод в том же контексте запроса, чтобы пакетировать save а также find вместе в одном запросе HTTP.
    Это то, что ты сделал. Он отправляет разницу изменений и извлекает свойства, необходимые для вашей панели просмотра. Можно сказать, что у него есть недостаток, заключающийся в том, что он тесно связывает ваше всплывающее окно и панель просмотра, и вам решать, является ли это приемлемым компромиссом.
  • используйте объект, который вы отредактировали и отправили на сервер прямо на панели просмотра, без дополнительных данных по проводам.
    Хотя это кажется более простым, вы пропустите любые изменения, которые могли бы быть внесены в сущность другим пользователем (изменяет только сервер).

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

Последнее слово в отношении терминологии: вы очищаете драйвер редактора, чтобы скопировать значение поля обратно в объект / прокси, и (независимо, но последовательно) запускаете контекст запроса, чтобы отправить пакет методов сервиса и изменения прокси в сервер. Очистка драйвера редактора ничего не отправляет на сервер, это разные действия.

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