GWT MVP обновляет состояние активности при изменении места
Как лучше обновлять состояние активности при изменении места? Представьте, что у вас есть действие с представлением, которое отображает список категорий и список элементов в категории. Если выбрана другая категория, приложение переходит на новое место с идентификатором категории. Затем я хочу обновить только элементы, а не создавать новую активность, которая также перечитывает список категорий.
Мой нынешний подход такой:
public class AppActivityMapper implements ActivityMapper {
private ItemListActivity itemListActivity;
...
public Activity getActivity(final Place place) {
final Activity activity;
if (place instanceof ItemListPlace) {
if (itemListActivity == null) {
itemListActivity = new ItemListActivity((ItemListPlace) place, clientFactory);
} else {
itemListActivity.refresh((ItemListPlace) place);
}
activity = itemListActivity;
} else {
itemListActivity = null;
}
...
return activity;
}
...
3 ответа
Альтернативы:
слушать
PlaceChangeEvent
изнутри действия (вы можете использоватьFilteredActivityMapper
а такжеCachingActivityMapper
для кеширования активности в вашемActivityMapper
, так что это сокращено, чтобы только создать новую деятельность, когда спросят). †есть какой-то компонент слушать
PlaceChangeEvent
s и переводить их в бизнес-ориентированные события, то деятельность затем слушает эти события, а неPlaceChangeEvent
с, в остальном такой же, как указано выше.отделить деятельность от "экрана", сделать "экран" синглтон с
reset()
метод и вызвать этот метод из деятельностиstart
(возможно, передавая ID категории в качестве аргумента в этом случае). "Экран", являющийся одноэлементным, может затем загрузить список категорий только один раз.в вашем случае вы также можете просто поместить список категорий в общий кеш, чтобы вам не приходилось повторно использовать вашу деятельность, создав новую, список категорий будет извлечен один раз и помещен в кеш, последующее действие экземпляры будут просто использовать то, что находится в кеше. Это похоже на описанное выше, но проще, и кеш может использоваться другими частями приложения.
Хотя лично я предпочел бы придерживаться вашего подхода (за небольшим исключением, см. Ниже), так как он самый простой / простой. Отключение активности от "экрана" также является опцией; Команда GWT начала исследовать этот подход в образце "Расходы" (отделив ответственность за деятельность от ответственности докладчика с использованием MVP), но, к сожалению, никогда не заканчивала его.
Кроме этого, я не думаю, что какая-либо лучшая практика действительно появилась на данный момент.
†. Мне не нравится связывать свою деятельность с местами, где они используются (мне не очень нравится goTo
звонит либо, но еще не нашел чистой и простой альтернативы), поэтому я бы предпочел не использовать эту опцию; и точно так же, я бы не стал передавать это место конструктору действий и refresh
метод, как вы сделали, но скорее извлекать информацию из места и передать ее в деятельность (например, в вашем случае, дать только идентификатор категории для деятельности, а не ItemListPlace
пример; Я бы тогда просто позвонил setCategory
во всех случаях и даже не передавать идентификатор категории конструктору).
По моему мнению,
- Роль
ActivityMapper
чтобы вернуть вамActivity
изPlace
, - Роль
ActivityManager
это начатьActivity
отдан отActivityMapper
и остановить текущий, если он отличается. В вашем случае вы хотели бы "обновить / обновить" текущийActivity
,
Так что я бы изменил ActivityMapper
так как это всегда вернет мне тот же самый экземпляр Activity
для данного типа Place
, Хороший способ сделать это - использовать GIN и область видимости синглтона. ...in(Singleton.class)
ввести ваш Activity
,
Если вы сделаете это, при изменении URL-адреса, если место останется прежним (то есть ваш URL-адрес будет иметь одно и то же слово после # и до:), так что тип вашего места останется прежним, ActivityMapper
вернет вам тот же экземпляр Activity
Итак ActivityManager
ничего не будет делать на Activity
, Проверка л.126 ActivityManager
if (currentActivity.equals(nextActivity)) {
return;
}
Для меня у вас есть 2 варианта там. Первый, как сказал Томас, это слушать PlaceChangeEvent
в вашем Activity
, Новый Place
вы получите новые параметры внутри, основанные на новом заданном URL, и вы можете "обновить / обновить" свой Activity
,
Второе, что я нахожу больше в соответствии с шаблоном Activity/Place - это изменение ActivityManager
так что он вызывает метод обновления (место) на Activity
когда Activity
отданы ActivityMapper
это то же самое, что текущий Activity
,
Я еще не пробовал ни одно из этих решений, но скоро буду... Возможно, я смогу обновить этот пост в то время.
Вы можете найти больше информации в этой статье, которую я написал в своем блоге на эту тему
Вот небольшая схема, которую я сделал, чтобы помочь мне понять шаблон, надеюсь, он поможет:
Я бы не делал никакой логики в своем ActiviyMapper, кроме как возвращая действие, создавая новое или передавая предыдущее (или ноль). По моему мнению, картографу не нужно знать о refresh() или о том, что делают действия.
Если это так, то логика "refresh()" будет передана активу через место, где находится токен. Этот токен должен содержать информацию о состоянии запроса (новая страница, перезагрузка, идентификатор и т. Д.).
В действии сначала запрашивается представление, относящееся к этому действию (совет: синглтон, предоставленный ClientFactory - хорошая практика), затем он создает презентатор для этого представления и связывает их вместе.
Наконец, действие будет использовать токен с места, чтобы предоставить докладчику любую информацию о состоянии. И затем, это добавляет представление на странице.
По умолчанию полезно знать, что с местами и активностями, переход в одно и то же место ничего не делает (без перезагрузки). Но вы можете легко позаботиться об этом с помощью токена и картографа активности.
Надеюсь, вы найдете адаптированное решение для вашего случая. Удачи.