【问题标题】:JSF - Passing an f:param when the paginator is used in a ViewScoped beanJSF - 在 ViewScoped bean 中使用分页器时传递 f:param
【发布时间】:2024-04-25 02:50:02
【问题描述】:

当此页面加载时,它需要一个视图参数并使用转换器来获取一个对象。

使用分页器时出现以下错误,因为 viewParam 未传递给转换器

在 java.lang.Long.parseLong(未知来源) 在 com.civi.HelloWorld.controller.UserConverter.getAsObject(UserConverter.java:36)

每次页面刷新时都需要传递一个参数。

所以当在数据表中使用分页器时,我需要发送 f:param 以便 viewParam 使用转换器加载对象

<f:metadata>
     <f:viewParam 
        name="idUser" 
        value="#{userBean.tipTourUser}" 
        converter="#{userConverter}" 
        required="true" 
        requiredMessage="Bad request. Please use a link from within the system." />  
</f:metadata>


<h:form id="abc" styleClass="simpleformstyle">
<p:dataTable id="transactionsTable" 
     var="transaction" 
     resizableColumns="true" 
     value="#{userBean.tipTourUser.tips}" 
     rendered="#{not empty userBean.tipTourUser.tips}" 

     rows="2"
     paginator="true"
     paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
     rowsPerPageTemplate="1,2,3" 
     paginatorPosition="bottom" >

//SOMETHING LIKE THIS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
     <f:param name="idUser" value="#{userBean.tipTourUser.idUser}" />     
//SOMETHING LIKE THIS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

     <p:column>
         <f:facet name="header">
             <h:outputText style="float: left;" value="Date received" />    
         </f:facet>
         <h:outputText value="#{transaction.received}" >
             <f:convertDateTime pattern="d-M-yyyy" />
         </h:outputText>
     </p:column>
</p:dataTable>
</h:form>

用户豆

@ViewScoped
@Named
public class UserBean implements Serializable  { 

    private static final long serialVersionUID = 1L;

    @EJB
    private UserService userService;

    private User tipTourUser;

    private boolean editmode;


    //sets the edit mode and stores the original values
    public void edit() {
        editmode = true;       
    }


    //resets the original values and leaves the edit mode
    public void cancel() {
        editmode = false;
    }


    //saves updated values and leavers the edit mode
    public void save(User user) {                           
        tipTourUser = userService.updateUser(user);

        editmode = false;    
    }


    public boolean isEditmode() {
        return editmode;
    }


    public User getTipTourUser() {
        return tipTourUser;
    }


    public void setTipTourUser(User tipTourUser) {
        this.tipTourUser = tipTourUser;
    }

}

转换器

@Named
@RequestScoped
public class UserConverter implements Converter
{
    @EJB
    private UserService userService;


    public UserConverter() {
    }

    //get User object from idUser, key = idUser
    @Override
    public Object getAsObject(FacesContext arg0, UIComponent arg1, String key) throws ConverterException {          
        return userService.getUser(Long.parseLong(key));
    }


    @Override
    public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2) throws ConverterException {
        return arg2.toString();
    } 
}

【问题讨论】:

  • 您具体何时重新加载页面?有必要还是不能使用ajax?
  • 当我在数据表中使用分页(更改页面或使用 RowsPerPageDropdown)时,页面会重新加载并尝试获取 viewParam,但 f:param 目前没有传递任何内容跨度>
  • 您在数据表周围有一个h:form? PrimeFaces Datatable 分页默认不刷新页面。它是一个 AJAX 组件。
  • 它现在包裹在一个表单中,但结果相同

标签: jsf primefaces view-scope paginator viewparams


【解决方案1】:

您需要在数据表周围有一个h:form,然后它是一个 AJAX 组件,不会在分页时重新加载页面。

对于基本的 GET 页面链接,您必须将视图参数传递给每个重定向。否则它会丢失。像这样的:

<h:link>
    <o:param name="idUser" value="#{userBean.tipTourUser}" converter="#{userConverter}" />
    <f:param name="page" value="#{userBean.page}" />
</h:link>

提示:

使用 omnifaces o:param,因为它提供了一个转换器属性来保持你的转换逻辑 DRY。

【讨论】:

  • 通常你不需要它。您是否尝试过使用o:viewParam。否则,您必须显示更多 bean 代码才能获得更多帮助。