代码之家  ›  专栏  ›  技术社区  ›  karlgrz

动态生成ICE:commandbutton组件

  •  2
  • karlgrz  · 技术社区  · 16 年前

    我尝试了很多不同的事情,我认为会像预期的那样工作。但是,它们让我有些沮丧。这是独家新闻:

    我在JavaEE Web应用程序中使用冰面1.8个组件。我的目标是基于对数据库的查询在页面上呈现一堆ICE:commandbuttons。我希望这些按钮能够切换选择,稍后我将用于数据库的另一个查询的参数(基本上是一组用户的查询前端排序)。我希望输出看起来像这样:

    Deselected

    当我单击一个按钮时,我希望对我的页面进行以下更新:

    Selected

    当我静态创建页面上的按钮时,例如:

    <ice:commandButton id="seasonSEP09" style="background-color: #FFFFFF;" partialSubmit="true" actionListener="#{bean.updateSeasons}" value="2009-2010" />
    <ice:commandButton id="seasonSEP08" style="background-color: #FFFFFF;" partialSubmit="true" actionListener="#{bean.updateSeasons}" value="2008-2009" />
    <ice:commandButton id="seasonSEP07" style="background-color: #FFFFFF;" partialSubmit="true" actionListener="#{bean.updateSeasons}" value="2007-2008" />
    <ice:commandButton id="seasonSEP06" style="background-color: #FFFFFF;" partialSubmit="true" actionListener="#{bean.updateSeasons}" value="2006-2007" />
    

    这个很好用,每个按钮都像我期望的那样单独工作。我的backing bean被更新,参数被正确地添加到updatesSeasons()方法中,最后我的输出会生成正确的记录。

    但是,我知道这不是我想要的。我不想在系统中输入其他季节时更新这些。维护噩梦,对吧?

    所以我要做的是动态地生成这些ICE:commandbutton组件,这些组件基于我的数据库表中满是季节对象。下面是我正在使用的季节类:

    public class Season
    {
        String StartMonth;
        String Season;
    
        public String getStartMonth()
        {
            return StartMonth;
        }
        public void setStartMonth(String startMonth)
        {
            StartMonth = sweep;
        }    
        public void setSeason(String season)
        {
            Season = season;
        }
        public String getSeason()
        {
            return Season;
        }
    }
    

    非常简单。两个属性,我保证在数据库中是唯一的。

    下面是我使用的支持bean:

    public class Bean
    {
        public Bean()
        {
            defineSeasonsList();
        }
    
        public List<HtmlCommandButton> seasonsList;
    
        // seasonsList getter & setter omitted
    
        public List<String> selectedSeasons;
    
        // selectedSeasons getter & setter omitted
    
        private void defineSeasonsList()
        {
            seasonsList = new ArrayList<HtmlCommandButton>();
            selectedSeasons = new ArrayList<String>();
    
            try
            {
                hibernate.openTransaction();
    
                for(Season season:defineSeasonsListFromDataSource()))
                {
                    HtmlCommandButton button = new HtmlCommandButton();
    
                    button.setId("season" + season.getStartMonth());
                    button.setValue(season.getSeason);
                    button.setStyle("background-color: #FFFFFF;");
                    button.setPartialSubmit(true);
    
                    seasonsList.add(button);
                }                         
            } 
            catch (Exception e)
            {
                System.out.println("Error defining seasons list: " + e.getMessage());
            }
            finally
            {
                hibernate.commitTransaction();
            }               
        }
    
        public void updateSeasons(ActionEvent ae)
        {
            HtmlCommandButton selected = (HtmlCommandButton) ae.getComponent();
    
            if(selectedSeasons.contains(selected.getValue().toString()))
            {
                selectedSeasons.remove(selected.getValue().toString());   
                selected.setStyle("background: #FFFFFF;");
            }
            else
            {
                selectedSeasons.add(selected.getValue().toString());
                selected.setStyle("background: #009DD9; color: #FFFFFF;");
            }
        }
    }   
    

    好吧,我的困境来了。

    首先,我尝试呈现此标记:

    <p>
        <ice:panelGroup>
            <ice:panelSeries id="seasonsList" value="#{bean.seasonsList}" var="season">
                    <ice:commandButton binding="#{season}"/>                                        
            </ice:panelSeries>
        </ice:panelGroup>
    </p>     
    

    我得到这个输出:

    Bad Buttons

    因此,由于感到沮丧和冒险,我试图呈现这个标记来实现我的目标:

    <p>
        <ice:panelGroup>
            <ice:panelSeries id="seasonsList" value="#{bean.seasonsList}" var="season">
                    <ice:commandButton id="#{season.id}" partialSubmit="true" style="background-color: #FFFFFF" value="#{season.value}" actionListener="#{bean.updateSeasons}"/>                                        
            </ice:panelSeries>
        </ice:panelGroup>
    </p>   
    

    产生了以下stacktrace:

    2009年8月4日下午2:28:11 com.sun.faces.lifecycle.phase dophase 严重:jsf1054:(阶段ID:render_response 6,视图ID:/phase1.jspx)阶段执行期间引发异常:javax.faces.event.phaseEvent[source=com.sun.faces.lifecycleImpl@1a477b7] 2009年8月4日下午2:28:11 org.apache.catalina.core.standardwrappervalve invoke 严重:servlet persistent faces的servlet.service()servlet引发异常 java.lang.illegalargumentexception:季节.id_ 在JavaX.FACK.组件. UICOMPONTROBASE.ValueID(UICOMPONTROBASE.java:549) 在JavaX.FACK.组件. UICOMPONTROBASE.SETID(UICOMPONTROBASE.java:351) 在Javax.Fask.WebApp.UICMoPuntTaT.CytCeCo组件(UICOMPONTAGTAG.java:219) 在Javax.Fask.WebApp.UICMoMunTrimeCasic TabasBaseCueDeCar(UICOMMPONTRONICTAGASBASE. Java:486) 在JavaX.Fask.WebApp.UICOMPONTRONICICTAGBASE.FIDENETFICE(UICOMPONTRONTICICTAGASBASE. Java:670) 在JavaX.Fask.WebApp.UICMoMeNoTrimeCigBase.doStastTabg(UICOMMPONTRONICTAGASBASE. Java:1142) 在COM.ICESOFT.FACK.组件.CubdButtoTaG.doStAdTabg(CurdButtoTab.java:741) 在COM.ICESOFT.FACK. WebApp.Pals.Prace.ExcExtJSPLIFECKEOLL(PARSER . Java:204) 在COM.ICESOFT.FACK. WebApp.Pals.Prace.ExcExtJSPLIFECKEOLL(PARSER . Java:229) 在COM.ICESOFT.FACK. WebApp.Pals.Prace.ExcExtJSPLIFECKEOLL(PARSER . Java:229) 在COM.ICESOFT.FACK. WebApp.Pals.Prace.ExcExtJSPLIFECKEOLL(PARSER . Java:229) 在COM.ICESOFT.FACK. WebApp.Pals.Prace.ExcExtJSPLIFECKEOLL(PARSER . Java:229) 在COM.ICESOFT.FACK. WebApp.Pals.Prace.ExcExtJSPLIFECKEOLL(PARSER . Java:229) 在COM.ICESOFT.FACK. WebApp.Pals.Prace.ExcExtJSPLIFECKEOLL(PARSER . Java:229) 在COM.ICESOFT.FACK. WebApp.Pals.Prace.ExcExtJSPLIFECKEOLL(PARSER . Java:229) 在COM.ICESOFT.FACK. WebApp.Pals.Prace.ExcExtJSPLIFECKEOLL(PARSER . Java:229) 在COM.ICESOFT.FACK. WebApp.Pals.Prace.ExcExtJSPLIFECKEOLL(PARSER . Java:229) 在COM.ICESOFT.FACK. WebApp.Pals.Prace.ExcExtJSPLIFECKEOLL(PARSER . Java:229) 在COM.ICESOFT.FACK. WebApp.Pals.Prace.ExcExtJSPLIFECKEOLL(PARSER . Java:229) 在COM.ICESOFT.FACTS .WebApp.Pals.PalSel.PARSE(PARS.java:162) 在COM.ICESOFT.FACK.应用程序. D2DVIEWHANDEL.ReDeRebug(D2DVIEWHANDLL.java:464) 在COM.ICESOFT.FACK.应用程序. D2DVIEWHANDEL.ReDeVIEW(D2DVIEWHANDLL.java:153) 在COM.Sun.FACK.生命周期.ReDeRebug Seal. Excel(ReDeleRebug Seal.java:110) 在COM.Sun.FACK.生命周期.阶段. DopaFe(阶段. Java:100) 在COM.Sun.FACK.生命周期.LealEclipse Currim.LIFE(LealeCycliim.java:139) 在COM.ICESOFT.Fask.WebApp.http.Cyr.JSFLeVeCyExcExpor。Apple(JSFLIFECYCREXECUTROR。Java:17) 在COM.ICESOFT.FACK.上下文.查看2美元1美元.响应(查看.java:47) 在COM.ICESoFT.Frase.WebApp.http.servlet .Servlet请求响应.Services(Servlet RevestReal.java 197) 在COM.ICESoFT.Fask.WebApp.http.servlet。TraceBuldKeAdvultServlet $thRead Bug RealEdvestReal.Read Debug(TyRead BuffeldAdvestServlet,Java:36) 在COM.ICESOFT.FACK.上下文.View $ 2 .Service(View . Java:72) 在COM.ICESOFT.FACK.上下文.View .ServEdvices(View .java:133) 在COM.ICESOFT.FACK. WebApp.http.Cyr.SunLeVIEWServer . Service(SunLeVIEWServer . Java:52) 在COM.ICESOFT.FACK. WebApp.http.Cuff.Server代理服务器(ServPytoServ.java:11) 在COM.ICESOFT.FACK. WebApp.http.servlet .MeNaseSealServlet 4美元. Service(MexSeSsEnservservlet . Java:114) 在COM.ICESOFT.FACK. WebApp.http.Cuth.Sturn.PoaTraceServer Services(PoaService CurrServer . Java:24) 在COM.ICESoFT.Fask.WebApp.http.servlet .MevsSeNestservserv.Service(MeistSeSealServservlet .java:160) 在COM.ICESOFT.FACK. WebApp.http.servlet .SeSSeDe调调器1美元. Service(SeaStices调度程序. Java:42) 在COM.ICESOFT.FACTS .WebApp.http.servlet .thuleBulkGuangdAdvServServ.Service(THead BoeLoad AdvutoServlet,Java:19) 在COM.ICESOFT.FACK. WebApp.http.servlet .EndoAdvutsServlet . Service(EndoAdvutServlet . Java:63) 在COM.ICESOFT.FACK. WebApp.http.servlet .SeaStservePoService . Service(SeaStservePosij.java:62) 在COM.ICESOFT.FACK. WebApp.http.servlet .PooDistCurr.Service(PoxDisturia.java:23) 在COM.ICESOFT.FACK. WebApp.http.servlet .MistServlet .Service(Meservlet . Java:153) 在javax .servlet .http.httpservlet .Service(httpservlet .java:717) 在Org.Apache .Calalina .CorpApple .FieldFortualStudio.IntualDoFielter(Apple 在Org.Apache .Calalina .Cype .FieldFieldCork.DoFulter(Apple)FieldStork.java:206) 在Org.Acache .Calalina .Corn.StaldReAPPorToCor.调用(StaldReAPPorTime.java:233) 在Org.Acache .Calalina .Cort.Stand AdExtCort.Cube(Stand AdvutoTork.java:191) 在Org.Acache .Calalina .Corn.StaldHoistPort.CuoKe(StaldHistort.java:128) 在Org.Apache。Calalina。阀门。ErrorRePortVortual.CuoKe(ErrorRePortVortu.java:102) 在Org.Acache .Calalina .Cort.StRealEngEnValue.No调用(StaldEngEnValv.java:109) 在Org.Apache .Calalina .Cornor.CyoToAddio.Service(CyoToAddio.java:286) 在Org.Apache .CyoOut.HTTP11. HTTP11Posial.进程(HTTP11Port.java:845) 在Org.Apache .CyoOut.HTTP11. HTTP11Trase$HTTP11CornAccess处理程序.(HTTP11Pr.java:583) 在Org.Apache .Tomcat .UTI.NET .JooEndot$Works.Run(JooEndoPo.java:447) 在Java.Lang.Trime.Run(线程.java:619)

    我是在做我不该做的事吗?

    有没有更好的方法来实现这个目标?

    如果需要更多信息,我很乐意提供。

    提前谢谢,我的朋友们。

    更新 :

    因此,我尝试将季节列表集合从一个列表更改为另一个列表,并呈现一些不同的标记,例如:

    <p>
        <ice:panelGroup>
            <ice:panelSeries value="#{bean.seasonsList}" var="season">
                    <ice:commandButton partialSubmit="true" style="background-color: #FFFFFF" value="#{season}" actionListener="#{Phase1EventBean.updateSeasons}"/>                                        
            </ice:panelSeries>
        </ice:panelGroup>
    </p>
    

    并将defineSeasonsList()方法更改为:

    public void defineNationalSeasonsList()
    {
        try
        {
            seasonsList = new ArrayList<String>();
            selectedSeasonsList = new ArrayList<String>();
    
            hibernate.openTransaction();
    
            for(UedaNationalDates season:hibernate.getList(new UedaNationalDates(), QueryFactory.getUedaNationalSeasons(hibernate.getHibSession())))
            { 
                nationalSeasonsList.add(season.getSeason());
            }       
        } 
        catch (Exception e)
        {
            System.out.println("Error defining nationalMeasurementPeriods: " + e.getMessage());
        }
        finally
        {
            hibernate.commitTransaction();
        }               
    }
    

    这实际上呈现了我想要看到的所有按钮,并在我单击它们时将它们正确地添加到我的backing bean中的selected季后赛列表中,在我再次单击时将它们从中删除。

    但是,在用户界面上, 每一个 当我只单击一个按钮时,按钮似乎被切换。例如,当我单击2009-2010时,我看到的是:

    All Selected

    1 回复  |  直到 16 年前
        1
  •  2
  •   McDowell rahul gupta    16 年前
    <ice:commandButton binding="#{season}"/>
    

    绑定属性必须绑定到类型为的bean属性 UIComponent . 它在您希望框架为您提供对支持bean中组件的引用或提供来自支持bean的实例的地方使用。见第3.1.5节 JSF 1.2 spec 了解更多详细信息。


    <ice:commandButton id="#{season.id}"
       partialSubmit="true"
       style="background-color: #FFFFFF"
       value="#{season.value}"
       actionListener="#{Phase1EventBean.updateSeasons}"/>
    

    这个 id 属性不能是动态的-JSF将使用 clientId ( read this for more detail )


    编辑:

    但是,在用户界面上,当我只单击一个按钮时,每个按钮都会显示为被切换。

    我猜是吧 ice:panelSeries 不会像某些重复控件那样存储每行的组件状态(例如,DataTable)。记住,只有一个按钮实例,即使它在每个“行”中编码/解码一次。

    我从来没有用过冰面,但我建议把它绑在豆子上,就像这样:

    public class Bean {
    
      private final List<SelectionBean> seasonsList = Arrays.asList(
          new SelectionBean("Spring"), new SelectionBean("Summer"),
          new SelectionBean("Autumn"), new SelectionBean("Winter"));
    
      public List<SelectionBean> getSeasonsList() { return seasonsList; }
    
      public static class SelectionBean {
    
        private String season;
        private boolean selected;
    
        public SelectionBean() {}
        public SelectionBean(String season) { this.season = season; }
    
        public String getSeason() { return season; }
        public void setSeason(String season) { this.season = season; }
    
        public String toggle() {
          System.out.println("toggle " + season);
          selected = !selected;
          return null;
        }
    
        public String getStyle() {
          return selected ? "background-color: yellow" : "background-color: blue";
        }
      }
    }
    

    我已经将逻辑简化到了最低限度,但希望您能够了解如何修改逻辑,以恢复对休眠的支持。然后您的组件会变成这样:

    <ice:panelSeries value="#{bean.seasonsList}" var="item">
      <ice:commandButton partialSubmit="true"
         style="#{item.style}"
         value="#{item.season}"
         action="#{item.toggle}"/>                                        
    </ice:panelSeries>
    

    因此,对于列表中的每个项目,所有绑定都返回到一段状态(SelectionBean实例),并且您不会尝试在组件本身存储任何非声明性状态。

    我试着用 action 结束 actionListener 如果可以的话,它可以让JSF的东西远离Pojos。

    推荐文章