jsf在ViewScoped bean中传递方法表达式中的参数

时间:2012-12-17 07:42:38

标签: jsf-2 el managed-bean

我有一个由ViewScoped bean支持的jsf页面,它列出了一堆交易,如下面的

<ui:repeat value="#{transactions_byaccount.pageList}" var="item">
            <tr class="dataRow">
                <td class="dataCell cltdtransactionsdatetransaction">
                      <h:outputText value="#{item.datetransaction}" >
                        <f:convertDateTime pattern="EEE dd-MMM-yyyy HH:mm" />
                      </h:outputText>
                </td>
                ...
                ...

                <td colspan="2">
                    <span class="pagerDBspan" style="font-weight: bold;">
                        <h:commandLink action="#{transactions_byaccount.updateCategory('', item)}" >
                            <h:outputText value="Update"></h:outputText>        
                            <f:param name="pageNo" value="#{param.pageNo}" />
                            <f:param name="accountId" value="#{param.accountId}" />
                            <f:param name="sortOrder" value="#{param.sortOrder}" />
                            <f:param name="orderColumn" value="#{param.orderColumn}" />                                                                         
                        </h:commandLink>
                    </span>                                         
                </td>

当用户导航到该页面时,该链接将accountId作为参数传入,该参数映射到bean上的托管属性,如下所示

@ManagedProperty("#{param.accountId}")
private int accountId;

此时调用方法#{transactions_byaccount.updateCategory('',item)}传递'item'按预期工作。

用户还可以通过选择绑定到上面的accountId字段的页面上的下拉菜单并单击刷新按钮来更改帐户ID,该按钮将调用相关DAO以获取所选帐户的事务列表。但是,当用户点击按钮调用#{transactions_byaccount.updateCategory('',item)}时,我没有从新帐户中列出该项目,它会使用第一个帐户列表中的项目。

似乎问题出现在JSF生命周期的恢复位上。

任何帮助将不胜感激。如果需要,将添加更多细节。

由于 摩尼

编辑: 我的豆子

package applogic.transactions;

import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;
import javax.faces.bean.ViewScoped;
import javax.faces.model.SelectItem;

import applogic.Conns;

import finance.bean.TransactionsListBean;
import finance.dao.AccountsDAO;
import finance.dao.TransactionsDAO;
import finance.daobase.BusinessDAO;
import finance.model.Accounts;
import finance.model.Transactions;
import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

@ManagedBean(name = "transactions_byaccount")
@ViewScoped
public class Transactions_Byaccount extends TransactionsListBean implements Serializable {
    List<Transactions> resultList;

    boolean initialized;

    @ManagedProperty("#{param.accountId}")
    private int accountId;

    public SelectItem[] accountsSelections;

    @ManagedProperty("#{param.sortOrder}")
    private int sortOrder;

    public SelectItem[] sortOrderSelections;

    @ManagedProperty("#{param.orderColumn}")
    private int orderColumn;

    public SelectItem[] orderColumnSelections;

    public Transactions_Byaccount() {
         Connection cons = Conns.getConFinanceDB();
         List<Accounts> accountsList = AccountsDAO.List(cons);
         List<SelectItem> listOfAccountsSelectItems = new
         ArrayList<SelectItem>();

         for( Accounts temp : accountsList ) {
             listOfAccountsSelectItems.add(new SelectItem(temp.getId(), temp.getTitle()));
         }

         accountsSelections = listOfAccountsSelectItems.toArray(new SelectItem[listOfAccountsSelectItems.size()]);

         List<SelectItem> sortOrderList = new ArrayList<SelectItem>();
         sortOrderList.add(new SelectItem(1, "Asc"));
         sortOrderList.add(new SelectItem(2, "Desc"));       
         sortOrderSelections = sortOrderList.toArray(new SelectItem[sortOrderList.size()]);

         List<SelectItem> orderColumnList = new ArrayList<SelectItem>();
         orderColumnList.add(new SelectItem(1, "Transaction Date"));
         orderColumnList.add(new SelectItem(2, "Action Date"));      
         orderColumnList.add(new SelectItem(3, "Reconciled Date"));
         orderColumnSelections = orderColumnList.toArray(new SelectItem[orderColumnList.size()]);
    }

    public String updateCategories(String redirectURL) {
        String result = redirectURL;

        Connection cons = Conns.getConFinanceDB();
        for( Transactions temp : (List<Transactions>)this.getPageList() )
            TransactionsDAO.Update(cons, temp);

        resultList = null;

        if( redirectURL != null && redirectURL.length() == 0 )
            redirectURL = null;

        return redirectURL;
    }

    public String updateCategory(String redirectURL, Transactions arg) {
        String result = redirectURL;

        Connection cons = Conns.getConFinanceDB();
        TransactionsDAO.Update(cons, arg);

        resultList = null;

        if( redirectURL != null && redirectURL.length() == 0 )
            redirectURL = null;

        return result;
    }

    @PostConstruct
    public void refresh() {
        Connection con = Conns.getConFinanceDB();
        resultList = TransactionsDAO.ListByaccount(con, accountId, getCurrentPageNo(), getPageSize(), orderColumn, sortOrder);
        initialized = true;

    }

    public void reload() {
        Connection con = Conns.getConFinanceDB();
        resultList = TransactionsDAO.ListByaccount(con, accountId, getCurrentPageNo(), getPageSize(), orderColumn, sortOrder);
        initialized = true;

    }

    public String reload(String returnUrl) {
        Connection con = Conns.getConFinanceDB();
        resultList = TransactionsDAO.ListByaccount(con, accountId, getCurrentPageNo(), getPageSize(), orderColumn, sortOrder);
        initialized = true;     
        return returnUrl;
    }

    public Object getPageList() {


        return resultList;
    }

    public int getMaxCount() {
        Connection con = Conns.getConFinanceDB();
        int result = TransactionsDAO.CountByaccount(con, accountId);
        return result;
    }

    public int getAccountId() {
        return accountId;
    }

    public void setAccountId(int accountId) {
        this.accountId = accountId;
    }

    public SelectItem[] getAccountsSelections() {
        return accountsSelections;
    }

    public void setAccountsSelections(SelectItem[] accountsSelections) {
        this.accountsSelections = accountsSelections;
    }

    public int getSortOrder() {
        return sortOrder;
    }

    public void setSortOrder(int sortOrder) {
        this.sortOrder = sortOrder;
    }

    public SelectItem[] getSortOrderSelections() {
        return sortOrderSelections;
    }

    public void setSortOrderSelections(SelectItem[] sortOrderSelections) {
        this.sortOrderSelections = sortOrderSelections;
    }

    public int getOrderColumn() {
        return orderColumn;
    }

    public void setOrderColumn(int orderColumn) {
        this.orderColumn = orderColumn;
    }

    public SelectItem[] getOrderColumnSelections() {
        return orderColumnSelections;
    }

    public void setOrderColumnSelections(SelectItem[] orderColumnSelections) {
        this.orderColumnSelections = orderColumnSelections;
    }   

    public boolean isInitialized() {
        return initialized;
    }

    public void setInitialized(boolean initialized) {
        this.initialized = initialized;
    }

    public List<Transactions> getResultList() {
        return resultList;
    }

    public void setResultList(List<Transactions> resultList) {
        this.resultList = resultList;
    }
}

现在我的页面

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

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


<ui:composition template="/WEB-INF/templates/template_main.xhtml">
    <ui:param name="title" value="transactions"></ui:param>

    <ui:define name="operationalbar">
        <div>
            <span>
                <h:selectOneMenu value="#{transactions_byaccount.accountId}" >
                    <f:selectItems value="#{transactions_byaccount.accountsSelections}"/>
                </h:selectOneMenu>
            </span>
            <span>
                <h:commandLink action="#{transactions_byaccount.reload('')}">
                    <h:outputText value="Reload"></h:outputText>
                    <f:param name="pageNo" value="#{param.pageNo}" />
                    <f:param name="accountId" value="#{param.accountId}" />
                    <f:param name="sortOrder" value="#{param.sortOrder}" />
                    <f:param name="orderColumn" value="#{param.orderColumn}" />
                </h:commandLink>
            </span>         
            <span>
                <h:commandLink action="#{transactions_byaccount.updateCategories('')}">
                    <h:outputText value="Update Categories"></h:outputText>
                    <f:param name="pageNo" value="#{param.pageNo}" />
                    <f:param name="accountId" value="#{param.accountId}" />
                    <f:param name="sortOrder" value="#{param.sortOrder}" />
                    <f:param name="orderColumn" value="#{param.orderColumn}" />
                </h:commandLink>        
            </span>
        </div>
    </ui:define>

    <ui:define name="pagingbar">
        <div>
            <span>
                <h:commandLink title="Go to page first page" >
                    <h:outputText value="first"></h:outputText>
                        <f:param name="pageNo" value="#{transactions_byaccount.firstPage}" />
                        <f:param name="accountId" value="#{param.accountId}" />
                        <f:param name="sortOrder" value="#{param.sortOrder}" />
                        <f:param name="orderColumn" value="#{param.orderColumn}" />             
                </h:commandLink>
            </span>
            <span>
                <h:commandLink title="Go to page prev page">
                    <h:outputText value="prev"></h:outputText>
                        <f:param name="pageNo" value="#{transactions_byaccount.prevPage}" />
                        <f:param name="accountId" value="#{param.accountId}" />
                        <f:param name="sortOrder" value="#{param.sortOrder}" />
                        <f:param name="orderColumn" value="#{param.orderColumn}" />
                </h:commandLink>

            </span>
                <ui:repeat value="#{transactions_byaccount.pages}" var="item">
                    <span style="font-weight: #{item == transactions_byaccount.currentPageNo ? 'bold' : 'lighter' }">
                        <h:commandLink>
                            <h:outputText value="#{item}"></h:outputText>
                            <f:param name="pageNo" value="#{item}" />
                            <f:param name="accountId" value="#{param.accountId}" />
                            <f:param name="sortOrder" value="#{param.sortOrder}" />
                            <f:param name="orderColumn" value="#{param.orderColumn}" />

                        </h:commandLink>
                    </span>
                </ui:repeat>                

            <span>
                <h:commandLink title="Go to page next page">
                    <h:outputText value="next"></h:outputText>
                        <f:param name="pageNo" value="#{transactions_byaccount.nextPage}" />
                        <f:param name="accountId" value="#{param.accountId}" />
                        <f:param name="sortOrder" value="#{param.sortOrder}" />
                        <f:param name="orderColumn" value="#{param.orderColumn}" />
                </h:commandLink>
            </span>
            <span>
                <h:commandLink title="Go to page last page">
                    <h:outputText value="last"></h:outputText>
                        <f:param name="pageNo" value="#{transactions_byaccount.lastPage}" />
                        <f:param name="accountId" value="#{param.accountId}" />
                        <f:param name="sortOrder" value="#{param.sortOrder}" />
                        <f:param name="orderColumn" value="#{param.orderColumn}" />

                </h:commandLink>                
            </span>         
        </div>
        <div class="currentPagerIndex">

        </div>
    </ui:define>
    <ui:define name="maincontent">
        <table class="datatable">
            <thead>
                <tr class="headRow">
                    <td>datetransaction</td>
                    <td>description</td>
                    <td>amount</td>
                    <td>Edit</td>
                    <td>Delete</td>
                </tr>
            </thead>
            <ui:repeat value="#{transactions_byaccount.pageList}" var="item">
                <tr class="dataRow">
                    <td class="dataCell cltdtransactionsdatetransaction">
                          <h:outputText value="#{item.datetransaction}" >
                            <f:convertDateTime pattern="EEE dd-MMM-yyyy HH:mm" />
                          </h:outputText>
                    </td>
                    <td class="dataCell cltdtransactionsdescription">#{item.description}</td>
                    <td class="dataCell cltdtransactionsamount">#{item.amount}</td>
                    <td style="width: 45px">
                        <span class="pagerDBspan" style="font-weight: bold;">                   
                            <h:link outcome="transactions_edit" style="font-weight: bold;">
                                <h:outputText value="Edit"></h:outputText>
                                <f:param name="pageNo" value="#{param.pageNo}" />
                                <f:param name="itemId" value="#{item.id}" />
                            </h:link>
                        </span>                 
                    </td>
                    <td style="width: 45px">
                        <span class="pagerDBspan" style="font-weight: bold;">
                            <h:link  outcome="transactions_edit" >
                                <h:outputText value="Delete"></h:outputText>
                                <f:param name="pageNo" value="#{param.pageNo}" />
                                <f:param name="itemId" value="#{item.id}" />
                                <f:param name="deleteFlag" value="true" />                                  
                            </h:link>       
                        </span>                 
                    </td>
                </tr>
                <tr class="dataRow">
                    <td class="dataCell"></td>
                    <td class="dataCell" colspan="2">
                        <h:selectOneMenu value="#{item.fkCategoriesId}" >
                            <f:selectItems value="#{categories_edit.categories}"/>
                        </h:selectOneMenu>
                    </td>
                    <td colspan="2">
                        <span class="pagerDBspan" style="font-weight: bold;">
                            <h:commandLink action="#{transactions_byaccount.updateCategory('', item)}" >
                                <h:outputText value="Update"></h:outputText>        
                                <f:param name="pageNo" value="#{param.pageNo}" />
                                <f:param name="accountId" value="#{param.accountId}" />
                                <f:param name="sortOrder" value="#{param.sortOrder}" />
                                <f:param name="orderColumn" value="#{param.orderColumn}" />                                                                         
                            </h:commandLink>
                        </span>                                         
                    </td>
                </tr>
                <tr>
                    <td class="cssBottomLine" colspan="0"></td>
                </tr>                   
            </ui:repeat>
        </table>
    </ui:define>

    <ui:define name="bottomoperationalbarhost">
    </ui:define>

</ui:composition>
</html>

1 个答案:

答案 0 :(得分:0)

如果#{transactions_byaccount.pageList}在处理表单提交过程中与显示表单时的状态不一致,则会发生这种情况。

在处理表单提交的新HTTP请求期间,JSF将重申它以查找调用的操作并准备#{item}以传递它。请注意,在呈现HTML表单以进行显示的HTTP请求期间,这不会准备好。

此问题表示您正在基于过时(或过于新)变量初始化#{transactions_byaccount.pageList},这导致变量不兼容。你不应该这样做。您应该重写bean逻辑,使其在回发时初始化与显示期间完全相同的列表,然后仅在实际调用操作时更改它(因此,在action方法内)。

鉴于您正在使用视图范围的bean,您实际上应该已经设置,因为它实际上会记住后续请求的所有属性。也许您正在列表的getter方法中执行初始化。您根本不应该在getter方法中执行业务逻辑。你应该在(post)构造函数或action方法中做到这一点。