3

我正在使用 Primefaces 3.5 和 JSF2.1 (Mojarra) 进行项目

我创建了一个内部<p:tabView id="tabsVw" dynamic="false">有两个选项卡的 primefaces,每个选项卡都有一个 primefaces 数据表

 <h:form> 
        <p:tabView  dynamic="false">
        <p:ajax event="tabChange" listener="#{tstTab.onDtlTabChanged}" />

            <p:tab title="tab1">
                <p:dataTable value="#{tstTab.list1}" var="v1">
                    <p:column>
                        <h:outputText value="#{v1}"/>
                    </p:column>
                </p:dataTable>
            </p:tab>

            <p:tab title="tab2">
                <p:dataTable value="#{tstTab.list2}" var="v2">
                    <p:column>
                        <h:outputText value="#{v2}"/>
                    </p:column>
                </p:dataTable>          
            </p:tab>
        </p:tabView>
    </h:form>

并在 bean 内部(查看范围)

@ManagedBean
@ViewScoped
public class TstTab {

    private List<String> list1;
    private List<String> list2;

    public TstTab(){
        list1 = new ArrayList<String>();
        list2 = new ArrayList<String>();


        list1.add("List 1 - Str 1");
        list1.add("List 1 - Str 2");
        list1.add("List 1 - Str 3");
        list1.add("List 1 - Str 4");
        list1.add("List 1 - Str 5");

        list2.add("List 2 - Str 1");
        list2.add("List 2 - Str 2");
        list2.add("List 2 - Str 3");
        list2.add("List 2 - Str 4");
        list2.add("List 2 - Str 5");            
    }


    public void onDtlTabChanged(TabChangeEvent event) {
        System.out.println("000000000000000000");
    }


    public List<String> getList1() {
        System.out.println("11111111111111");
        return list1;
    }


    public List<String> getList2() {
        System.out.println("222222222222222222");
        return list2;
    }

}

现在的问题是当运行应用程序并尝试在选项卡之间导航(更改)时,但我可以看到onDtlTabChanged在调用 getter 之后调用了,所以这是一个大问题。

如果tabView从静态更改为动态,则行为是随机的,换句话说,对更改事件的调用发生在 getter 中间的某个地方。

先感谢您。

4

3 回答 3

4

好吧,我认为这是一个primefaces BUG,我找到了一种解决方法,如下所示

  1. 不要使用全局表单(tabView 本身的表单),而是为每个选项卡使用一个表单(在它内部围绕数据表)

  2. 您必须添加一个虚拟选项卡作为第一个必须包含其中一些静态数据或预加载数据的表单的选项卡

就这样,

问题是 ajax 请求在全局表单中,它导致数据表在 ajax 请求之前首先获取它们的数据,Primefaces 的奇怪之处在于,如果您不添加第一个虚拟选项卡,它将始终执行第一个表单选项卡并获取其数据,这将导致问题

问候 ,

于 2013-04-11T11:07:44.747 回答
2

我认为阿里萨利赫的答案是正确的。

如果您在使用 tabchangelistener 时遇到问题,也许这可以帮助您:

我对 Primefaces 5.1 有类似的问题

只要我将 tabview 放入表单中,一切正常。但是因为我想在我的选项卡中使用单独的表单,所以我不得不删除 tabview 的周围表单以避免嵌套表单。如果没有周围的表单,则在更改选项卡时不再触发 ajax 事件。

我的解决方案是以与 tabview 平行的形式使用远程命令。
远程命令由 tabview 元素的 onTabChange 属性触发。在那次调用中,我将索引参数转发到全局请求参数。

<p:tabView id="rootTabMenu" styleClass="tabcontainer" prependId="false" 
        activeIndex="#{sessionData.activeTabIndex}" widgetVar="rootTabMenu"
        onTabChange="tabChangeHelper([{name: 'activeIndex', value: index}])">
    // Tabs...  
</p:tabView>

<h:form id="tabChangeHelperForm">
    <p:remoteCommand name="tabChangeHelper" actionListener="#{sessionData.onTabChange()}" />
</h:form>    

在支持 bean 中,我再次从请求参数映射中捕获了值并设置了活动索引。

public void onTabChange()
{   
    FacesContext context = FacesContext.getCurrentInstance();
    Map<String, String> paramMap = context.getExternalContext().getRequestParameterMap();
    String paramIndex = paramMap.get("activeIndex");
    setActiveTabIndex(Integer.valueOf(paramIndex));
    System.out.println("Active index changed to " + activeTabIndex);
}    

希望能帮到你

于 2014-11-14T10:06:39.623 回答
1

它在 Primefaces 3.5 和 mojarra 2.1.20 中运行良好,我的代码:bean:

@ManagedBean(name = "tabview")
@ViewScoped    
public class TabView implements Serializable {

        private static final long serialVersionUID = 1L;
        private List<Car> l1;
        private List<Car> l2;
        private List<Car> l3;

        public TabView() {
            l1 = new ArrayList<Car>();
            l2 = new ArrayList<Car>();
            l3 = new ArrayList<Car>();

            Car c1 = new Car("c1", "a1");
            Car c2 = new Car("c21", "a21");
            Car c3 = new Car("c31", "a31");
            Car c4 = new Car("c41", "a41");
            Car c5 = new Car("c51", "a51");
            Car c6 = new Car("c61", "a61");
            Car c7 = new Car("c71", "a71");
            Car c8 = new Car("c81", "a81");
            Car c9 = new Car("c91", "a91");
            l1.add(c1);
            l1.add(c2);
            l1.add(c3);

            l2.add(c4);
            l2.add(c5);
            l2.add(c6);

            l3.add(c7);
            l3.add(c8);
            l3.add(c9);
        }

        public void hand(TabChangeEvent event) {
            Car c1 = new Car("c1", "a1");
            Car c2 = new Car("c1", "a1");
            Car c3 = new Car("c1", "a1");
            Car c4 = new Car("c1", "a1");
            Car c5 = new Car("c1", "a1");
            Car c6 = new Car("c1", "a1");
            Car c7 = new Car("c1", "a1");
            Car c8 = new Car("c1", "a1");
            Car c9 = new Car("c1", "a1");
            l1.add(c1);
            l1.add(c2);
            l1.add(c3);

            l2.add(c4);
            l2.add(c5);
            l2.add(c6);

            l3.add(c7);
            l3.add(c8);
            l3.add(c9);
        }

        public List<Car> getL1() {
            return l1;
        }

        public void setL1(List<Car> l1) {
            this.l1 = l1;
        }

        public List<Car> getL2() {
            return l2;
        }

        public void setL2(List<Car> l2) {
            this.l2 = l2;
        }

        public List<Car> getL3() {
            return l3;
        }

        public void setL3(List<Car> l3) {
            this.l3 = l3;
        }
    }

xhtml:

  <p:tabView id="mtrlDtlTabs" dynamic="true" cache="false">  
                    <p:ajax event="tabChange" update="t1 t2 t3" listener="#{tabview.hand}"/>
                    <p:tab id="t1" title="1">
                        <p:dataTable id="l1" value="#{tabview.l1}" var="l1">
                            <p:column headerText="l1">#{l1.manufacturer}</p:column>
                            <p:column headerText="l2">#{l1.model}</p:column>
                        </p:dataTable>
                    </p:tab>
                    <p:tab id="t2" title="2">
                        <p:dataTable id="l2" value="#{tabview.l2}" var="l2">
                            <p:column headerText="l2">#{l2.manufacturer}</p:column>
                            <p:column headerText="l22">#{l2.model}</p:column>
                        </p:dataTable>
                    </p:tab>
                    <p:tab id="t3" title="3">
                        <p:dataTable id="l3" value="#{tabview.l3}" var="l3">
                            <p:column headerText="l3">#{l3.manufacturer}</p:column>
                            <p:column headerText="l33">#{l3.model}</p:column>
                        </p:dataTable>
                    </p:tab>
                </p:tabView>
于 2013-04-11T14:24:25.577 回答