【问题标题】:Primefaces tabview tabChange event fired after displaying tabPrimefaces tabview tabChange 显示选项卡后触发的事件
【发布时间】:2013-04-02 13:08:32
【问题描述】:

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

我创建了一个 primefaces <p:tabView id="tabsVw" dynamic="false"> 里面有两个选项卡,每个选项卡都有一个 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 中间的某个地方。

提前谢谢你。

【问题讨论】:

  • 你设置了dynamic="true",那你为什么要在ajax中更新tab 1呢?
  • 我有 cache="false",所以如果用户导航到第二个选项卡然后转到第一个选项卡,我必须再次重新获取数据
  • 那么如果用户导航到第二个标签然后转到第三个标签?
  • 我不明白你的意思,这个想法是有三个选项卡,每个选项卡都有一个数据表,每次用户单击选项卡时我都需要刷新数据,但 Primefaces 之前正在加载选项卡内容完成 changeTab ajax 事件
  • 我用 Primefaces 3.5 和 jsf(morjarra 2.1.20) 进行了测试,它工作正常,所以你应该先用简单的例子测试并参考上面的代码,祝你好运!

标签: primefaces tabs tabview


【解决方案1】:

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

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

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

就是这样,

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

问候,

【讨论】:

    【解决方案2】:

    我认为ali saleh的答案是对的。

    如果您在使用 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);
    }    
    

    希望对你有帮助

    【讨论】:

    • 请不要只链接到答案。允许在此处显示解决方案链接到答案。这样,当 url 不再有效时,提问者仍然知道该怎么做。
    【解决方案3】:

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

    @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>
    

    【讨论】:

    • 尝试在getter中添加打印语句,你会发现调用它们的顺序很奇怪
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-07
    • 1970-01-01
    • 1970-01-01
    • 2015-10-18
    • 1970-01-01
    • 1970-01-01
    • 2017-03-14
    相关资源
    最近更新 更多