代码之家  ›  专栏  ›  技术社区  ›  Sechanris

使用JSF selectOneListbox存储Liferay 7 portlet首选项

  •  4
  • Sechanris  · 技术社区  · 6 年前

    我正在将Liferay 6.2中的JSF portlet升级到Liferay 7。

    portlet显示图标列表和 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 在更改后调用 选择一个列表框 ,portlet会将新选项保存到portlet首选项,并调用bean的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 从更改为项目,如 选择一个列表框 ,而不是提交表单?如果没有,正确的方法是什么?

    1 回复  |  直到 6 年前
        1
  •  2
  •   Tobias Liefke    6 年前

    您应该始终使用 现在的 要求当您使用会话bean的构造函数中的首选项(通常首先从渲染请求调用)时,首选项仍然与(过时的)渲染请求相连接。

    我的意思是:

    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();
        }
        ...
    }