隨筆-112  評(píng)論-73  文章-0  trackbacks-0
          jsf 傳參數(shù)主要有以下幾種方式:

          As to the cause, the <f:attribute> is specific to the component itself (populated during view build time), not to the iterated row (populated during view render time).

          There are several ways to achieve the requirement.

          1. Use <f:param> instead. It adds a request parameter.

            <h:commandLink action="#{bean.insert}" value="insert">
               
            <f:param name="id" value="#{item.id}" />
            </h:commandLink>

            If your bean is request scoped, let JSF set it by @ManagedProperty

            @ManagedProperty(value="#{param.id}")
            private Long id; // +setter

            Or if your bean has a broader scope or if you want more fine grained validation/conversion, use<f:viewParam> on the target view, see also f:viewParam vs @ManagedProperty:

            <f:viewParam name="id" value="#{bean.id}" required="true" />

            Either way, this has the advantage that the datamodel doesn't necessarily need to be preserved for the form submit (for the case that your bean is request scoped).


          2. Use <f:setPropertyActionListener> instead. The advantage is that this removes the need for accessing the request parameter map when the bean has a broader scope than the request scope.

            <h:commandLink action="#{bean.insert}" value="insert">
               
            <f:setPropertyActionListener target="#{bean.id}" value="#{item.id}" />
            </h:commandLink>

            In combination with

            private Long id; // +setter

            It'll be just available by property id in action method. This only requires that the datamodel is preserved for the form submit request. Best is to put the bean in the view scope by @ViewScoped.


          3. If your servletcontainer supports Servlet 3.0 / EL 2.2, then just pass it as method argument. This also requires that the datamodel is preserved for the form submit request. Best is to put the bean in the view scope by @ViewScoped.

            <h:commandLink action="#{bean.insert(item.id)}" value="insert" />

            In combination with:

            public void insert(Long id) {
               
            // ...
            }

            You can even pass the entire item object:

            <h:commandLink action="#{bean.insert(item)}" value="insert" />

            with:

            public void insert(Item item) {
               
            // ...
            }

            On Servlet 2.5 containers, this is also possible if you supply an EL implementation which supports this, like as JBoss EL. For configuration detail, see this answer.


          4. Bind the datatable value to DataModel<E> instead which in turn wraps the items.

            <h:dataTable value="#{bean.model}" var="item">

            with

            private transient DataModel<Item> model;

            public DataModel<Item> getModel() {
               
            if (model == null) {
                    model
            = new ListDataModel<Item>(items);
               
            }
               
            return model;
            }

            (making it transient and lazily instantiating it in the getter is mandatory when you're using this on a view or session scoped bean since DataModel doesn't implement Serializable)

            Then you'll be able to access the current row by DataModel#getRowData() without passing anything around (JSF determines the row based on the request parameter name of the clicked command link/button).

            public void insert() {
               
            Item item = model.getRowData();
               
            Long id = item.getId();
               
            // ...
            }

            This also requires that the datamodel is preserved for the form submit request. Best is to put the bean in the view scope by @ViewScoped.


          5. You can use Application#evaluateExpressionGet() to programmatically evaluate the current #{item}.

            public void insert() {
               
            FacesContext context = FacesContext.getCurrentInstance();
               
            Item item = context.getApplication().evaluateExpressionGet(context, "#{item}", Item.class);
               
            Long id = item.getId();
               
            // ...
            }

          Which way to choose depends on the functional requirements and whether the one or the other offers more advantages for other purposes. I personally would go ahead with #3 or, when you'd like to support servlet 2.5 containers as well, with #2.

          posted on 2012-07-13 19:42 Libo 閱讀(620) 評(píng)論(0)  編輯  收藏 所屬分類: JSF 2

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 勐海县| 皋兰县| 宁远县| 遵义县| 南充市| 墨竹工卡县| 瑞昌市| 金川县| 江川县| 合江县| 乐至县| 石台县| 鹿邑县| 柘城县| 越西县| 永泰县| 鄯善县| 治县。| 仙游县| 石泉县| 泸溪县| 普定县| 南阳市| 酉阳| 宾阳县| 马山县| 尖扎县| 普定县| 海门市| 闸北区| 博客| 兴安县| 成武县| 内丘县| 镇沅| 鹰潭市| 金溪县| 凌海市| 邯郸县| 阜康市| 元阳县|