p:accordionPanel 标签标题未显示

p:accordionPanel tab title not showing

我的 JSF 2.2 应用程序中有一个动态手风琴面板,它从命名 bean 获取其值。例如

    <p:accordionPanel id="formsPanel" value="#{formController.forms}" var="form"
        rendered="#{not empty formController.forms}">
        <p:tab title="#{form.name}">
        </p:tab>
    </p:accordionPanel>

已成功列出所有选项卡,但标题为空。

我有另一个用于向列表中添加表单的面板

    <p:accordionPanel rendered="#{not empty formController.forms}">
        <p:tab title="Add form">
            <h:form id="addFormForm1">
                <p:panelGrid columns="3" layout="grid">
                    <h:outputText value="Form name" />
                    <p:inputText value="#{formController.form.name}" />
                    <p:commandButton update="formsPanel" action="#{formController.createForm}"
                        value="Add form" />
                </p:panelGrid>
            </h:form>
        </p:tab>
    </p:accordionPanel>

inputText 应该设置表单 bean 的名称,但它似乎没有这样做

我的 FormController 中的代码看起来像这样

@Named
@ViewScoped
public class FormController
{

    private List<Form> forms;

    @Inject
    @Named("formService")
    private CouchbaseFormService formService;

    private Form form = new Form();

    public void createForm()
    {
        try
        {
            formService.create(form);
        } catch (CouchbaseServiceException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        form = new Form();
    }

    public Form getForm()
    {
        return form;
    }

    public void setForm(Form form)
    {
        this.form = form;
    }

    public List<Form> getForms()
    {
        return forms;
    }

    public void setForms(List<Form> forms)
    {
        this.forms = forms;
    }

    @PostConstruct
    public void init()
    {
        try
        {
            forms = formService.findAll();
        } catch (CouchbaseServiceException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

表单是一种 Widget

@Named
public class Widget
{
    protected String name;

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

     //Other stuff
}

和你看不到的形式没什么特别的

@Named
public class Form extends Widget
{
    //Form related code
}

尽管如此,我还是不明白为什么 <p:tab title="#{form.name}"> 没有在选项卡的标题中向我显示表单的名称

我也曾尝试将手风琴面板中的 var 名称从 form 更改为 formInstance 但这没有帮助,我还从两者中删除了 @Named Form class 和 Widget class

如果我以调试模式启动服务器并在 createForm 方法中放置一个断点,我可以看到 FormController 表单实例成员的名称确实为 null。

那么为什么 <p:inputText value="#{formController.form.name}" /> 没有正确设置表单的名称?

编辑:

我已经成功创建了 SSCCE

这是 XHTML

<!DOCTYPE html>
<html xmlns="http://www.w3c.org/1999/xhtml"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:p="http://primefaces.org/ui">
<h:head>
    <title>Forms</title>
</h:head>
<h:body>
    <p:accordionPanel id="formsPanel" value="#{formController.forms}"
        var="formInstance" rendered="#{not empty formController.forms}">
        <p:tab title="#{formInstance.name}">
        </p:tab>
    </p:accordionPanel>
    <p:accordionPanel rendered="#{not empty formController.forms}">
        <p:tab title="Add form">
            <h:form id="addFormForm1">
                <p:panelGrid columns="3" layout="grid">
                    <h:outputLabel value="Form name:" />
                    <p:inputText value="#{formController.form.name}" required="true"
                        label="text" />
                    <p:commandButton update="formsPanel"
                        action="#{formController.createForm}" value="Add form" />
                </p:panelGrid>
            </h:form>
        </p:tab>
    </p:accordionPanel>
</h:body>
</html>

这是 FormService,请忽略这不是提供服务的方式,它只是演示问题的一种方式。

@Named
public enum FormService
{

    INSTANCE(new ArrayList<Form>());

    private List<Form> forms;

    private FormService(List<Form> forms)
    {
        this.forms = forms;
        this.forms.add(new Form("Form 1"));
    }

    public void createForm(Form form)
    {
        forms.add(form);
    }

    public List<Form> findAll()
    {
        return forms;
    }

}

FormController

@Named
@ViewScoped
public class FormController
{

    private FormService formService;

    private List<Form> forms;

    public Form form = new Form();

    @PostConstruct
    public void init()
    {
        formService = FormService.INSTANCE;
        forms = formService.findAll();
    }

    public void createForm()
    {
        formService.createForm(form);
        form = new Form();
    }

    public List<Form> getForms()
    {
        return forms;
    }

    public void setForms(List<Form> forms)
    {
        this.forms = forms;
    }

    public Form getForm()
    {
        return form;
    }

    public void setForm(Form form)
    {
        this.form = form;
    }

}

Form

public class Form
{

    private String name;

    public Form()
    {

    }

    public Form(String name)
    {
        this.name = name;
    }


    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

}

正如您在下面的屏幕截图中看到的那样,初始化它的初始表单看起来没问题,但是添加一个带有名称的表单只会呈现一个没有标题的新选项卡

我所做的是放置几个断点,一个在 Form.setName 中,一个在 FormController.createForm 中。

当输入表单名称并单击“添加表单”时,这两种方法都会被调用。

首先,setForm 是用一个表单 object 引用调用的(例如)com.test.Form@30998fa6,它的名称是正确的。

然后使用表单 object 引用 com.test.Form@2ad84d0f 调用 createForm,名称为空。我不明白的是为什么这些显然是两种不同的形式 objects.

另一个症状是@PostConstruct 被多次调用而不是一次。

好的,经过更多的挖掘,我找到了答案。这有帮助

当我切换到使用 @ManagedBean 时,它开始工作了。我不确定的是我正在使用 Glassfish 4 并且我的 POM

中有以下依赖项
    <dependency>
        <groupId>javax.faces</groupId>
        <artifactId>javax.faces-api</artifactId>
        <version>2.2</version>
        <scope>provided</scope>
    </dependency>

所以我的印象是我正在使用 JSF 2.2,那么为什么它不能与 @Named

一起使用

当你使用 javax.faces.bean.ViewScoped 时使用'@ManagedBean。当您使用 import javax.faces.view.ViewScoped 使用 '@Named 时提到这里 https://jsflive.wordpress.com/2013/07/17/jsf22-cdi-view-scope/