如何在 p:tabView 组件中动态添加和删除选项卡

Posted

技术标签:

【中文标题】如何在 p:tabView 组件中动态添加和删除选项卡【英文标题】:How to dynamically add and remove a tab in p:tabView component 【发布时间】:2011-11-10 15:12:16 【问题描述】:

我正在尝试动态添加 PrimeFaces <p:tab>。添加第二个选项卡时,出现以下异常:

“java.lang.IllegalStateException: 组件 ID tab0 已在视图中找到”。

我该如何解决这个问题?

查看代码如下:

<h:form prependId="false">
    <p:tabView id="tabview" dynamic="true" cache="false" 
        binding="#testBean.tabView" 
        activeIndex="#testBean.activeTab" >  
        <h:commandButton value="Close" action="#testBean.removeTab"/>
    </p:tabView>  
    <h:commandButton value="Add Tab" action="#testBean.addTab"/>
</h:form>

这是 bean 代码:

public String addTab() 
    String tabId="tab"+id;
    System.out.println("Gen Id: "+tabId);
    tab = new Tab();
    tab.setTitle("Title: "+tabId);
    tab.setId(tabId);

    System.out.println("Tab Id: "+tab.getId());
    tabView.getChildren().add(id,this.tab);
    id++;
    return "tabtest.jsf";


public String removeTab() 
    tabView.getChildren().remove(activeTab);
    return "tabtest.jsf";

【问题讨论】:

看来id 管理不善。您能否发布更多代码(例如 id 的声明)? BWT,如果你想留在同一页面上tabtest.jsf,你的方法可以返回void @janasoft : 你能告诉我们你是如何解决这个问题的吗(如果现在已经解决了)? 【参考方案1】:

如果一切都可以在视图中完成,请不要手动创建组件。如果 bean 的范围比请求范围更广,则此构造将失败。另见例如Binding attribute causes duplicate component ID found in the view

遵循展示示例“TabView with Model”,它允许您通过健全的模型动态填充选项卡,&lt;p:tabView value="..." var="..."&gt; 就像 &lt;ui:repeat&gt;/&lt;h:dataTable&gt;

例如这个观点

<h:form>
    <p:tabView value="#bean.tabs" var="tab">  
        <p:tab title="#tab.title">
            #tab.content
            <p:commandButton value="Close" action="#bean.remove(tab)" update="@form" />
        </p:tab>
    </p:tabView>  
    <p:commandButton value="Add Tab" action="#bean.add" update="@form" />
</h:form>

用这个控制器

@ManagedBean
@ViewScoped
public class Bean implements Serializable 

    private List<Tab> tabs;

    @PostConstruct
    public void init() 
        tabs = new ArrayList<>();
    

    public void add() 
        tabs.add(new Tab("tab" + tabs.size(), "some content"));
    

    public void remove(Tab tab) 
        tabs.remove(tab);
    

    public List<Tab> getTabs() 
        return tabs;
    


还有这个模型

public class Tab 

    private String title;
    private String content;

    public Tab(String title, String content) 
        this.title = title;
        this.content = content;
    

    public String getTitle() 
        return title;
    

    public String getContent() 
        return content;
    


【讨论】:

太好了,我不知道标签可以这样生成! +1【参考方案2】:

这是因为正在为新标签(您添加的标签)生成相同的 ID。为避免这种情况,请将变量附加到 id

<p:tabView id="tabview_#testBean.i" dynamic="true" cache="false"binding="#testBean.tabView" 
        activeIndex="#testBean.activeTab" >  
        <h:commandButton value="Close" action="#testBean.removeTab"/>
 </p:tabView>  

【讨论】:

这将通过拥有不同的 id 来工作。你能告诉我投票这个没有用的原因吗?分享你的代码

以上是关于如何在 p:tabView 组件中动态添加和删除选项卡的主要内容,如果未能解决你的问题,请参考以下文章

PrimeNG - 如何在 p-tabView 组件中动态添加和删除 p-tabPanel

Primefaces tabview 验证与动态选项卡

角度 5 - 如何从 dom 中删除动态添加的组件

Angular 表单:如何动态添加/删除子表单组件

如何在 JSF 中动态添加字段?

JSF - tabView 中的动态选项卡数量,具有动态选项卡内容