1

停工一段时间后,我又回来做一些 xpages,我似乎已经忘记了很多事情。我有以下代码:

数据源:

<xe:objectData var="league" ignoreRequestParams="true" scope="request">
    <xe:this.saveObject><![CDATA[#{javascript:leagueService.set(league)}]]></xe:this.saveObject>
    <xe:this.createObject><![CDATA[#{javascript:return leagueService.get(viewScope.currentKey);}]]></xe:this.createObject>
</xe:objectData>

和几个组合框

    <xp:comboBox id="idLeagueList" value="#{viewScope.currentKey}">
        <xp:selectItems>
            <xp:this.value><![CDATA[#{javascript: return eu.jeroensomhorst.cms.util.JSFUtil.asSelectItem(leagueService.getAll(season),true);}]]></xp:this.value>
        </xp:selectItems>   
        <xp:eventHandler event="onchange" submit="true" refreshMode="complete"></xp:eventHandler>
    </xp:comboBox>

    <xp:listBox id="lstAvailableTeams">
        <xp:selectItems>
            <xp:this.value><![CDATA[#{javascript:eu.jeroensomhorst.cms.util.JSFUtil.asSelectItem(teamService.getAll());}]]></xp:this.value>
        </xp:selectItems>
    </xp:listBox>

和一个按钮,将 lstAvailableTeams 中的选定团队添加到选定的 leage 对象

    <xp:button value="&#62;" id="addTeam" >
                <xp:eventHandler event="onclick" submit="true" refreshMode="complete" disableValidators="true">
                    <xp:this.action>
                        <xp:actionGroup>
                            <xp:executeScript>
                                <xp:this.script><![CDATA[#{javascript:var teamList = getComponent("lstAvailableTeams");
    var strTeamKey = teamList.getValue();
    eu.jeroensomhorst.cms.util.LeagueUtil.addTeam(league.getKey(),strTeamKey);}]]></xp:this.script>
                            </xp:executeScript>
                        </xp:actionGroup>
                    </xp:this.action></xp:eventHandler></xp:button>

    <xp:listBox id="leagueTeams">
            <xp:selectItems>
                <xp:this.value><![CDATA[#{javascript:return eu.jeroensomhorst.cms.util.JSFUtil.asSelectItem(league.getTeams());}]]></xp:this.value>
            </xp:selectItems>
    </xp:listBox>

Leagueutil 的代码如下所示:

public static void addTeam(String leagueKey,String key){
    LeagueService lService = (LeagueService) DominoUtil.getVariableValue("leagueService");

    League l = (League) lService.get(leagueKey);
    TeamService service = (TeamService) DominoUtil.getVariableValue("teamService");
    Team t = service.get(key);
    Vector<Team> teams = l.getTeams();
    if(teams == null){
        teams = new Vector();
        teams.add(t);
    }else{
        if(!teams.contains(t)){
            teams.add(t);
        }
    }

    l.setTeams(teams);
    // save into database.. this works.
    lService.set(l);

}

因为你看不出有什么好看的。但问题如下。每当我更改 idLeagueList 组合框值并执行 changelistener 时(它会更新 viewscope )。它总是检索显示在 Leagueteams 组合框中的先前值。这是一个非常基本的问题,但我完全没有选择..

4

1 回答 1

2

createObject of objectData gets executed too early: before the restore view phase is completed. This way objectData gets the old value from viewScope.currentKey.

createObject:           viewScope.currentKey = old value
afterRestoreView:       viewScope.currentKey = old value
beforeRenderResponse:   viewScope.currentKey = new value

A possible way to solve your issue is to use a view scope variable for league object instead. You can set it in beforePageLoad and beforeRenderResponse events.

viewScope.league = leagueService.get(viewScope.currentKey)

and use it in listBox

... eu.jeroensomhorst.cms.util.JSFUtil.asSelectItem(viewScope.league.getTeams())

and button code

... eu.jeroensomhorst.cms.util.LeagueUtil.addTeam(viewScope.league.getKey(),strTeamKey)

Here is a short version of your code for test purposes. It shows the current value of viewScope.currentKey at several JSF phases with print statements:

<?xml version="1.0" encoding="UTF-8"?>
<xp:view
    xmlns:xp="http://www.ibm.com/xsp/core"
    xmlns:xe="http://www.ibm.com/xsp/coreex">
    <xp:this.afterRestoreView><![CDATA[#{javascript:print ("afterRestoreView: " + viewScope.currentKey)}]]></xp:this.afterRestoreView>
    <xp:this.beforeRenderResponse><![CDATA[#{javascript:print ("beforeRenderResponse: " + viewScope.currentKey)}]]></xp:this.beforeRenderResponse>
    <xp:this.afterRenderResponse><![CDATA[#{javascript:print ("afterRenderResponse: " + viewScope.currentKey)}]]></xp:this.afterRenderResponse>
    <xp:this.data>
        <xe:objectData
            var="league"
            ignoreRequestParams="true"
            scope="request">
            <xe:this.createObject><![CDATA[#{javascript:
                if (viewScope.currentKey == null) viewScope.currentKey = "aaa"; 
                print("createObject: " + viewScope.currentKey); 
                viewScope.currentKey}]]>
            </xe:this.createObject>
        </xe:objectData>
    </xp:this.data>
    <xp:comboBox
        id="idLeagueList"
        value="#{viewScope.currentKey}">
        <xp:selectItems>
            <xp:this.value><![CDATA[#{javascript: return ["aaa","bbb"];}]]></xp:this.value>
        </xp:selectItems>
        <xp:eventHandler
            event="onchange"
            submit="true"
            refreshMode="complete">
        </xp:eventHandler>
    </xp:comboBox>
    <xp:listBox
        id="leagueTeams">
        <xp:selectItems>
            <xp:this.value><![CDATA[#{javascript:
                print("listBox: league = " + league + " viewScope.currentKey=" + viewScope.currentKey); 
                if (league === "aaa") return ["aaa1","aaa2"]; else return ["bbb1","bbb2"]}]]>
            </xp:this.value>
        </xp:selectItems>
    </xp:listBox>
</xp:view>
于 2013-09-07T12:34:08.153 回答