【问题标题】:JSF 1.2: valueChangeListener event not returning newly selected valueJSF 1.2:valueChangeListener 事件不返回新选择的值
【发布时间】:2010-12-24 02:22:19
【问题描述】:

我有这个支持 bean:

public class PageBean 
{
    private List<SelectItem> selectPages;
    private List<SelectItem> selectRowsPerPage;
    private String selectedPage;
    private String selectedRowsPerPage;
    private int pages = 0;

// getter methods
public boolean getRender()
{
    boolean rendered = pages > 0? true: false;
    return rendered;
}   

public List<SelectItem> getSelectPages() 
{
    int value = 0;

    selectPages = new ArrayList<SelectItem>();
    for (int i = 1; i < (pages + 1); i++) 
    {
        if (i > 1) { value = i * 10; }
        selectPages.add(new SelectItem(Integer.toString(value), Integer.toString(i)));
    }   

    return selectPages;
}

public String getSelectedPage()
{
    if (selectedPage == null) {
        selectedPage = "1";
    }

    return selectedPage;
}

// setter methods
public void setSelectPages(List<SelectItem> selectPages) {
    this.selectPages = selectPages;
}  

public void setSelectedPage(String selectedPage) {
    this.selectedPage = selectedPage;
}    

// action methods
public void changePage(ValueChangeEvent event)
{
    PhaseId phase = event.getPhaseId();

    if (phase.equals(PhaseId.INVOKE_APPLICATION)) {
        System.out.println((String) event.getNewValue());
        setSelectedPage((String) event.getNewValue());
        FacesContext.getCurrentInstance().renderResponse();
    } else {
        event.setPhaseId(PhaseId.INVOKE_APPLICATION);
        event.queue();
    } 
}    
}

而 h:selectOneMenu 是:

<h:selectOneMenu id="page" value="#{pageBean.selectedPage}"
   valueChangeListener="#{pageBean.changePage}" onchange="submit()">
   <f:selectItems value="#{pageBean.selectPages}" />
</h:selectOneMenu>

changePage() 方法的上述代码不会从 h:selectOneMenu 返回新的选定页面值。相反,它会在提交之前返回页面值。我不明白为什么。

有人可以帮忙吗?现在已经卡了2天了。

【问题讨论】:

  • 这个问题得到了著名的观点,原因很明显

标签: java jsf valuechangelistener


【解决方案1】:

显然您正在执行重定向而不是转发,而 bean 是请求范围的。重定向会创建一个 new 请求,从而垃圾所有初始请求范围的属性,包括请求范围的 bean。因此,它将导致重新创建具有所有默认属性的请求范围 bean。要解决此问题,请从faces-config.xml 中的&lt;navigation-case&gt; 条目中删除&lt;redirect/&gt; 条目(如果有)。

如果这是纯粹的页面到页面导航,我会推荐另一种方法。去掉 valueChangeListener,将页面 URL 设为 SelectItem 值,并将 submit() 替换为:

onchange="window.location=this.options[this.selectedIndex].value"

您不想使用POST 进行简单的页面到页面导航。

希望这会有所帮助。

编辑: 根据 cmets,您实际上想要数据表分页,并且此下拉菜单必须立即转到同一 JSF 页面的数据表的第 X 页?在这种情况下,忘记我上面的答案,你的问题并不清楚,我没有意识到你想要数据表分页。

目前发布的信息和代码看起来不错。您是否调试过代码以查看属性值会发生什么?不是后来就废了吗?渲染期间返回的值是否正确?下拉列表是否在渲染期间返回预期的项目?那种琐碎的事情。也许您没有发布的其他内容正在与这一切发生冲突。

编辑 2: 我实际上创建了一个 SSCCE 以查看它是否真的有效,并且正如我所料,它确实有效。你的问题出在其他地方。也许是一辆越野车Converter?也许它实际上是一个重定向?

MyBean(请求范围):

public class MyBean {

    private Integer page;
    private List<SelectItem> pages = new ArrayList<SelectItem>();

    public MyBean() {
        for (int i = 1; i <= 10; i++) {
            pages.add(new SelectItem((i == 1) ? i : (i * 10)));
        }
    }

    public void changePage(ValueChangeEvent event) {
        if (event.getPhaseId() == PhaseId.INVOKE_APPLICATION) {
            setPage((Integer) event.getNewValue());
        } else {
            event.setPhaseId(PhaseId.INVOKE_APPLICATION);
            event.queue();
        }
    }

    public Integer getPage() {
        return page;
    }

    public List<SelectItem> getPages() {
        return pages;
    }

    public void setPage(Integer page) {
        this.page = page;
    }

}

(顺便说一句,您使用了String 而不是Integer,这是错误的数值类型,但在这里它也适用于String

JSF 页面:

<h:form>
    <h:selectOneMenu value="#{myBean.page}" onchange="submit()"
        valueChangeListener="#{myBean.changePage}">
        <f:selectItems value="#{myBean.pages}" />
    </h:selectOneMenu>
</h:form>

我在 Tomcat 6.0.20 上使用了 Mojarra 1.2_13。

顺便说一句,valueChangeListener 完全是多余的。没有它它也能正常工作。 JSF 只是在Update Model Values 阶段设置选定的页面。

【讨论】:

  • @BalusC:不,我的 faces-config.xml 中根本没有定义 指令。当调用 onchange() 方法时,该方法会抓取选定的页面(加上表单上的 3 个其他选定值)并将所有这些值传回数据库以进行数据检索。如果我选择第 2 页,数据库应该返回记录 11 到 20,因为我限制每页 10 条记录。提交表单后,selectOneMenu 应显示页面“2”。你博客中的分页方式和我的要求不一样,所以不能采用。上面的 JS 建议是唯一的解决方案吗?...
  • 糟糕!为我上面的错字道歉。上面的方法应该是:onchange="pageChanged(),其中 pagechanged 是一个 JavaScript 函数,它等于:document.getElementById("Form1:btnSubmit").click();。btnSubmit 后面的函数就是我在我之前的评论。我很感谢你或任何可以帮助我解决这个问题的人。
  • 我可以添加一个 h:inputHidden 字段来存储更改后的页面值,以便在提交表单时,我可以从隐藏字段中检索值。如果这是可能的,我如何在支持 bean 中定义 getter/setter 方法。我是 JSF 的新手,所以我真的不知道该怎么做。如果您知道,请提供一些示例代码。
  • @BalusC:是的,提交后,selectOneMenu 会重新填充正确的页面列表 - 但提交后未选择先前选择的页面,即。重新选择列表中的第一项。另外,在我上面的 getSelectedPage() 方法中,如果返回的页面值为空,则默认为“1”(因为我不能让页面为空)。我认为这是重新提交表单时发生的情况。是因为我正在使用 getSelectPages() 方法重新填充页面吗?我想知道这是否是它在 JSF 阶段丢失先前选择的页面值的原因。
  • 运行调试器。我在迄今为止发布的信息中没有看到问题。其他东西正在与此发生冲突。
猜你喜欢
  • 2013-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-26
  • 2011-12-18
  • 1970-01-01
  • 2011-09-16
  • 1970-01-01
相关资源
最近更新 更多