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.
Это то, что ты сделал. Он отправляет разницу изменений и извлекает свойства, необходимые для вашей панели просмотра. Можно сказать, что у него есть недостаток, заключающийся в том, что он тесно связывает ваше всплывающее окно и панель просмотра, и вам решать, является ли это приемлемым компромиссом. - используйте объект, который вы отредактировали и отправили на сервер прямо на панели просмотра, без дополнительных данных по проводам.
Хотя это кажется более простым, вы пропустите любые изменения, которые могли бы быть внесены в сущность другим пользователем (изменяет только сервер).
В общем, я думаю, что я бы пошел с текущим решением. Что касается вашего кода, я бы запустил всплывающее окно с прокси и обратным вызовом и оставил контекст запроса и драйвер редактора редактирования в качестве подробностей реализации всплывающего окна: вам нужно только, чтобы оно вызывало панель представления обратно, когда это было сделано, передавая обновленный прокси в качестве аргумента для обратного вызова.
Последнее слово в отношении терминологии: вы очищаете драйвер редактора, чтобы скопировать значение поля обратно в объект / прокси, и (независимо, но последовательно) запускаете контекст запроса, чтобы отправить пакет методов сервиса и изменения прокси в сервер. Очистка драйвера редактора ничего не отправляет на сервер, это разные действия.