【问题标题】:How to call a managed bean method from an outputLink?如何从 outputLink 调用托管 bean 方法?
【发布时间】:2014-02-15 03:18:44
【问题描述】:

这可能已经在某处被覆盖,但我在为搜索引擎形成问题时遇到了麻烦,到目前为止还没有商品线索。

我正在开发一个充当实体视图的页面。许多结果来自数据库,一次只显示少数结果。所以你可以想象我想建立一个链接列表,将用户带到另一个实体页面。这是我所有的代码——没有 PrimeFaces 或任何其他前端漂亮的分页解决方案。至少现在是这样。

到代码:

@Named
@SessionScoped
public class ArticleIndexBean {
    List<Article> articleList=new ArrayList<>();
    List<Article> articleSubList=new ArrayList<>();

@PostConstruct
public void loadScreenSupport() {
    search();
    toEntityPage(1);
    }

protected void search() {
        // this method sets articleList which is the full list fetched from the database
    }

public void toEntityPage(int pageNumber) {
       // this method sets articleSubList which is a subset of articleList 
}

每个页面链接都需要调用toEntiyPage(n)。我知道 commandLink 但我想避免 POST 请求。此外,该 bean 当前是会话范围的,稍后我将尝试将其设置为会话范围。它肯定不会是请求范围的,因为我不想每次用户想要跳转到另一个页面时都进行完整的数据库搜索。所以@PostConstruct 也无济于事。

因此,使用这样的菜单:1 * 2 * 3 * 4 * 5 如何编写 outputLink 或任何其他类型的链接,以通过 GET 请求调用我的 ArticleIndexBean.toEntityPage(int)

解决方案

根据 Laurent 的输入,我向我的 bean 添加了一个 currentEntityPageNumber 属性和一个 toCurrentEntityPage() 方法。 toCurrentEntityPage() 只是调用toEntityPage(getCurrentEntityPageNumber())

<html lang="en"
  xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="http://java.sun.com/jsf/html"
  xmlns:f="http://java.sun.com/jsf/core"
  xmlns:ui="http://java.sun.com/jsf/facelets"
  >

<f:metadata>
    <f:viewParam name="pn" value="#{articleIndexBean.currentEntityPageNumber}" />
    <f:event type="preRenderView" listener="#{articleIndexBean.toCurrentEntityPage()}" />
</f:metadata>

<c:forEach var="pageNumber" begin="1" end="${articleIndexBean.getEntityPageCount()}">   
                <h:outputLink value="ar_index.xhtml">
                        <h:outputText value="${pageNumber}" />
                        <f:param name="pn" value="${pageNumber}" />
                </h:outputLink>
    </c:forEach>

如果我们可以直接调用toEntityPage(pageNumber) 肯定会更好,但这很好用。

【问题讨论】:

    标签: jsf pagination managed-bean


    【解决方案1】:

    假设您使用的是JSF 2.2,您可以使用viewParam在GET参数中检索页面,并使用viewAction在渲染前调用方法(实际上默认在INVOKE_APPLICATION阶段调用)。

    小脸:

    <f:metadata>
        <f:viewParam name="page" value="#{articleIndexBean.entityPage}" />
        <f:viewAction action="#{articleIndexBean.loadScreenSupport}" />
    </f:metadata>
    

    如果您使用的是 JSF 2.0 或 JSF 2.1,则必须将 viewAction 替换为:

    <f:event type="preRenderView" listener="#{articleIndexBean.loadScreenSupport}" />
    

    Java:

    @Named
    @SessionScoped
    public class ArticleIndexBean {
        List<Article> articleList=new ArrayList<>();
        List<Article> articleSubList=new ArrayList<>();
    
        int pageNumber = 1; // by default first page
    
        public void loadScreenSupport() {
            search();
            toEntityPage(pageNumber);
        }
    
        public int getPageNumber() {
            return pageNumber;
        }
    
        public void setPageNumber(int pageNumber) {
            this.pageNumber = pageNumber;
        }
    
        protected void search() {
            // this method sets articleList which is the full list fetched from the database
        }
    
        public void toEntityPage(int pageNumber) {
           // this method sets articleSubList which is a subset of articleList 
        }
    }
    

    到页面的链接很容易:

    <h:outputLink value="resultPage.xhtml">
        <h:outputText value="2" />
        <f:param name="page" value="2" />
    </h:outputLink>
    

    参考:

    【讨论】:

    • 我使用的是 TomEE 1.6,所以我坚持使用 myfaces-api-2.1.13.jar。遵循您针对 Faces 2.1 或更早版本的解决方案,我遇到了&lt;f:metadata&gt; 的麻烦。我应该如何定义f 命名空间?
    • 我的代码示例只是我正在做的一小部分。分页实际上是在另一个视图中实现的。出于某种原因,我在那里遇到了问题,并认为这些问题与 f:metadata 声明有关。现在,我知道他们不是。您的解决方案工作正常。谢谢洛朗。
    猜你喜欢
    • 2013-01-24
    • 1970-01-01
    • 2012-03-26
    • 2023-03-27
    • 1970-01-01
    • 2013-09-10
    • 2013-03-24
    • 1970-01-01
    • 2013-04-16
    相关资源
    最近更新 更多