2012-03-20 3 views
2

Позвольте мне начать с того, что у меня есть решение, но на самом деле я не думаю, что он изящный. Итак, я ищу более чистый способ сделать это.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(); 

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

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

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

ответ

1

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

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

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

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

Выполнение этой задачи устраняет проблему с отправкой rf объекта целиком с помощью fire(), а не только на diff. Однако я не знаю, почему. Это может быть ошибкой в ​​драйвере редактора RF.

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

2

Вы, кажется, не понимаете деталей того, что происходит с RF; плюс, ваша терминология на самом деле не помогает понять (flush vs. fire).

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

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

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

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

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

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

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

+0

Спасибо за ваш ответ, но я не уверен, где вы думаете, что я перепутал флеш и огонь. Я использовал их точно так, как вы описали. Также в RequestFactoryEditorDriver flush возвращает rf-контекст, с которым вы его инициализировали, а не отредактированный объект, который не позволяет вашему третьему варианту быть возможным (если только не существует какого-либо доступа, который я не нашел). Также, глядя на отправленный HTTP-запрос, весь объект отправляется на сервер не только с дельтами, что отличается от способа документирования rf. И условие, которое вы дали, когда событие EntityProxyChange является условием ... – Deanna

+0

Я рассмотрел ваш вариант 1, но, как вы отметили, это дополнительная поездка на сервер. Я использовал вариант 2, но он работает не так, как ожидалось, поскольку он не отправляет diff. До того, как этот процесс начался, объект уже был на сервере и появился на панели просмотра. Это файл playerProfile, на который я ссылаюсь в примере кода. Я использую это для инициализации RequestFactoryEditorDriver, поэтому я ожидаю, что событие сработает (firewall eventbus firef), когда драйвер покраснеть и/или исходный прокси обновится. Упускаю ли я что-то, что мешает этим? – Deanna

+0

Кроме того, я не полностью использовал случай использования entityproxy только в качестве моментального снимка, когда вы его схватили. В этом вы правы. Я думал, что это нечто более функциональное, как удаленная/клиентская копия объекта, которая будет обновлена, если я возьму новую копию того же объекта с сервера и отправит событие entityproxychange. – Deanna

Смежные вопросы