RequestFactoryEditorDriver получает отредактированные данные после сброса - PullRequest
2 голосов
/ 20 марта 2012

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

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

Я столкнулся с проблемой, потому что RequestFactoryEditorDriver потока всплывающего редактора не позволяет вам получить доступ к отредактированным данным.Драйвер использует тот же передаваемый в контексте контекст, который используется для отправки данных на сервер, однако контекст, возвращаемый из сброса, допускает Receiver<Void>, даже если вы приведете его к типу контекста, который вы сохранили в драйвере редактора при редактировании () вызов.[ Похоже, что оно также не отправляет и событие 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 ().Хотя этот подход работает, он не кажется правильным.[ Может показаться, что я должен подписаться на событиеменимый объект в отображаемом представлении и обновить сущность и представление оттуда.- еще раз, та же причина, что и раньше ] Также этот подход сохраняет полную сущность, а не только измененные биты, что увеличит использование полосы пропускания.

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

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

Ответы [ 2 ]

2 голосов
/ 20 марта 2012

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

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

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

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

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

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

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

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

1 голос
/ 21 марта 2012

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

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

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

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

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

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

...