Сохранение настроек портлета Liferay 7 с использованием JSF selectOneListbox
Я обновляю портлет JSF, который был у нас в Liferay 6.2, до Liferay 7.
В портлете отображается список значков и selectOneListbox
используется для управления отображением этих значков.
<h:selectOneListbox id="listModeSelector" value="#{user.listMode}" size="1">
<f:selectItems value="#{user.listModes}" var="mode"
itemLabel="#{mode.label}" itemValue="#{mode.value}" />
<f:ajax event="change" execute="@this" render=":metricsPanel" />
</h:selectOneListbox>
когда user.setListMode
вызывается после изменения selectOneListbox
портлет сохранит новую опцию в настройках портлета с вызовом к PortletPreferences компонента setValue
а также store
функции:
@ManagedBean
@SessionScoped
public class User {
private static final String LIST_MODE_KEY = "listMode";
private ListMode listMode;
private PortletPreferences preferences;
public User() {
PortletRequest request = ((PortletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest());
preferences = request.getPreferences();
listMode = ListMode.fromValue( preferences.getValue( LIST_MODE_KEY, ListMode.Normal.getValue() ) );
}
public String getListMode() {
return listMode.getValue();
}
public ListMode[] getListModes() {
return ListMode.values();
}
public void setListMode( String listModeValue ) {
this.listMode = ListMode.fromValue( listModeValue );
try {
preferences.setValue( LIST_MODE_KEY, listModeValue );
preferences.store();
}
catch ( ...Exception e ) {
log.error( "unable to persist listMode: " + e.getMessage(), e );
}
}
}
Когда они меняют эту настройку, мы хотим, чтобы она оставалась неизменной для них, для любых будущих сессий. Но после перехода на Liferay 7 это вызывает IllegalStateException
с сообщением Preferences cannot be stored inside a render call
,
Итак, мой вопрос: в Liferay 7 JSF, есть ли способ хранить PortletPreferences
от изменения до предмета вроде selectOneListbox
вместо отправки формы? Если нет, каков будет правильный способ сделать это?
1 ответ
Вы всегда должны использовать параметры портлета текущего запроса. Поскольку вы используете предпочтения из конструктора вашего сессионного компонента, который обычно вызывается сначала из запроса рендеринга, предпочтения по-прежнему связаны с (устаревшим) запросом рендеринга.
Я имею в виду, как это:
public void setListMode( String listModeValue ) {
this.listMode = ListMode.fromValue( listModeValue );
try {
PortletPreferences preferences = ((PortletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest()).getPreferences();
preferences.setValue( LIST_MODE_KEY, listModeValue );
preferences.store();
}
...
}