используя viewScope
рекомендуется. избегать использования вида корня (компонент в целом) атрибуты по двум причинам:
в теории, существует вероятность того, что вы перезаписать атрибут вид корневого компонента. на практике это невозможно, так как ключи атрибутов реализованы с enum
(по крайней мере, в mojarra)
UIComponentBase.getAttributes
возвращает конкретную реализацию Map
: AttributesMap
. эта реализация сначала проверяет, существует ли метод с тем же именем ключа карты в компоненте. а если нет, он проверяет внутреннюю карту. если он снова не найден, он проверяет карту ValueExpression
. поэтому он не эффективен вообще и, в частном случае, может привести к бесконечной рекурсии.
взглянуть на AttributesMap.get
, в примере:
public Object get(Object keyObj) {
String key = (String) keyObj;
Object result = null;
if (key == null) {
throw new NullPointerException();
}
if (ATTRIBUTES_THAT_ARE_SET_KEY.equals(key)) {
result = component.getStateHelper().get(UIComponent.PropertyKeysPrivate.attributesThatAreSet);
}
Map<String,Object> attributes = (Map<String,Object>)
component.getStateHelper().get(PropertyKeys.attributes);
if (null == result) {
PropertyDescriptor pd =
getPropertyDescriptor(key);
if (pd != null) {
try {
Method readMethod = pd.getReadMethod();
if (readMethod != null) {
result = (readMethod.invoke(component,
EMPTY_OBJECT_ARRAY));
} else {
throw new IllegalArgumentException(key);
}
} catch (IllegalAccessException e) {
throw new FacesException(e);
} catch (InvocationTargetException e) {
throw new FacesException(e.getTargetException());
}
} else if (attributes != null) {
if (attributes.containsKey(key)) {
result = attributes.get(key);
}
}
}
if (null == result) {
ValueExpression ve = component.getValueExpression(key);
if (ve != null) {
try {
result = ve.getValue(component.getFacesContext().getELContext());
} catch (ELException e) {
throw new FacesException(e);
}
}
}
return result;
}
думать о своем реквизита, она не имеет никакого смысла, по крайней мере, с точки WebAPP зрения. состояние состояния состояния запоминает состояния компонентов: значения модели компонента, которые изменяются из состояния inital и должны быть обработаны следующим образом. если эти значения не должны обрабатываться, то не нужно долго прочитывать их. мы можем думать о них как о «преходящем».наоборот, если их нужно обрабатывать и запоминать в течение длительного времени, настойчивость - это путь. действительно, я не могу представить ни одного случая для такого рода данных, чтобы выжить в течение более длительного времени, чем сеанс, и короче, чем навсегда (настойчивость).
Вы можете рассказать нам пример реальной жизни?
Самый лучший пример, который приходит мне в голову, - это помнить активный индекс для tabView или аккордеона, но это значение может (и должно) сохраняться, если это важно.
однако каждая проблема имеет решение, первое, что я могу думать, это то, что вы можете реализовать настраиваемую область, которая сохраняет эти значения в области приложения, используя определенное значение cookie (client) в качестве ключа.
но viewcope хранится в сеансе и, таким образом, он теряется, когда пользовательский сеанс уничтожается (что происходит очень быстро в моем приложении), поэтому как я могу заставить данные viewcope выжить даже после того, как сессия разрушится? Должен ли я разрабатывать пользовательскую реализацию для этих данных? есть идеи? –
Вид сериализуется в сеансе, если ваш государственный метод сохранения - это сервер. Если этот метод является клиентом, состояние представления сериализуется, кодируется как base64 и отправляется в браузер, где он хранится в скрытом поле и отправляется обратно на сервер при выполнении следующего запроса. Таким образом, даже если сеанс истекает на сервере, клиент предоставит это состояние просмотра и будет успешно восстановлен. –
Глядя на реализацию UIViewRoot, атрибуты компонента сохраняются вместе с картой вида, поэтому их жизненный цикл должен быть одинаковым. Какую реализацию и версию JSF вы используете? –