【问题标题】:jsf2 commandButton, commandLink doesn't trigger actionjsf2 commandButton,commandLink 不触发动作
【发布时间】:2012-12-31 18:49:34
【问题描述】:

在此页面中,h:commandButton 不会触发托管 bean 中的操作方法,但是当我单击按钮时,它会重新加载当前页面。我不知道为什么请帮忙。

    <?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE composition 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:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      >
  <h:head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Bootstrap 101 Template</title>
    <!-- Bootstrap -->
    <h:outputStylesheet library ="css" name="bootstrap.css"/>
    <h:outputStylesheet library ="css" name="bootstrap-responsive.css"/>
    <h:outputScript library="js" name="bootstrap.js"/>
    <h:outputScript library="js" name="bootstrap-responsive.js"/>
  </h:head>
  <h:body>
      <h:form>           
                              <label><h3>Search</h3></label>


                              <h:selectOneMenu id="searchtype" value="#{searchView.searchType}" style="width: 230px">
                                  <f:selectItems value="#{searchView.searchType}"/>

                              </h:selectOneMenu>
                              <br/>
                              <h:inputText id="searchvalue" value="#{searchView.searchvalue}" required="true" style="height: 30px; width: 230px">
                                  <p:watermark value="Search type" for="searchvalue"/>
                              </h:inputText>
                              <br/>

                              <h:commandButton id="searchbtn" value="Search" action="#{searchView.prepareSearchResultView()}" styleClass="btn"/>

      </h:form>
  </h:body>
</html>

我的 searchView 托管 bean 是会话范围的,这里是托管 bean 中的 prepareSearchResultView() 方法;

    public String prepareSearchResultView(){

    this.searchResultList = searchCustomer();
    if(!this.searchResultList.isEmpty()){
        this.citizenSearchResultList = getCitizenSearchList();
        this.orgSearchResultList = getOrganizationSearchList();
        if(getCitizenSearchList().getRowCount() >0){
            return "citizensearchlist";
        }else if(getOrganizationSearchList().getRowCount()>0){
            return "orgsearchlist";
        }

    }else
        return "nosearchresult";
    //FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "no such result", "no such result"));
    return null;
}

和 getSearchType() 方法

    public Map<String, Object> getSearchType(){
    Map<String, Object> returnMap = new LinkedHashMap<String, Object>();
    if(loginview.isAbleToGetCitizenInfo() || loginview.isUserAdmin()){
        returnMap.put("searchtype1", "searchcitizenbyregno");
        returnMap.put("searchtype2", "searchcitizenbyname");
    }
    if(loginview.isAbleToGetOrgInfo() || loginview.isUserAdmin()){
        returnMap.put("searchtype3", "searchorgbyregno");
        returnMap.put("searchtype4", "searchgorgbyname");
        returnMap.put("searchtype5", "searchorgbystateregno");
    }
    return returnMap;
}

【问题讨论】:

  • 你能详细解释一下这个问题吗?您的托管 bean 的范围是什么,您也可以添加 prepareSearchResultView 的代码吗?点击命令按钮后你想实现什么,你想改变一些东西还是你想导航到另一个页面?
  • 发布您的searchView 代码显示使用的注释
  • 顺便说一句:永远不要在 getter 中执行业务逻辑。另见stackoverflow.com/questions/2090033/…

标签: jsf-2 commandbutton


【解决方案1】:

您以错误的方式使用&lt;h:selectOneMenu&gt;。您在 selectMenu 中的值是地图,如果不使用转换器,您无法从选择菜单中设置地图类型的值。在选择项中,您应该将 value 属性绑定到托管 bean 中的某个字符串。然后在您的 actionMethod 中,您可以使用此选定类型从地图中检索选定的值。

<h:selectOneMenu id="searchtype" value="#{searchView.selectedType}" style="width: 230px">
    <f:selectItems value="{searchView.searchType}"/>
</h:selectOneMenu>

请查看以下帖子以更好地理解该概念:Primefaces selectOneMenu listener not called with Objects other than Strings

通过执行业务逻辑的 getter 检索 f:selectItems 值也不是一个好习惯。您应该在托管 bean 中创建一个属性,该属性在构造函数中初始化该映射。与其使用地图,不如使用列表并将您的键和值封装在自定义对象中。

<h:selectOneMenu id="searchtype" value="#{searchView.selectedType}" style="width: 230px">
    <f:selectItems value="{searchView.searchType}" 
                   var="searchType" 
                   itemLabel=#{searchType.key} 
                   itemValue=#{searchType.value}/>
</h:selectOneMenu>

List<RowItems> searchType = Lists.newArrayList(); // guave constructor

@PostConstruct
public void initBean(){
    if(loginview.isAbleToGetCitizenInfo() || loginview.isUserAdmin()){
        searchType.add(new RowItems("searchType1", "searchcitizenbyregno"));
        searchType.add(new RowItems("searchtype2", "searchcitizenbyname"));
    }
    if(loginview.isAbleToGetOrgInfo() || loginview.isUserAdmin()){
        searchType.add(new RowItems("searchtype3", "searchorgbyregno"));
        searchType.add(new RowItems("searchtype4", "searchgorgbyname"));
        searchType.add(new RowItems("searchtype5", "searchorgbystateregno"));
    }
}

public List<RowItems> getSearchType(){
    return searchType
}

最后,您的prepareSearchList 函数的最后一条语句return null 不是必需的,应将其删除,因为根据您发布的内容,它是无法访问的代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多