p:accordionPanel标签标题未显示

时间:2015-12-04 11:04:48

标签: jsf primefaces accordion title

我的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班级和Widget班级

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

那么为什么没有<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;
    }

}

正如您在下面的屏幕截图中看到的那样初始化的初始表单显示正常,但添加带有名称的表单只会呈现一个没有标题的新标签

enter image description here

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

键入表单名称并单击“添加表单”时,将调用这两种方法。

首先使用Form对象引用(例如)com.test.Form@30998fa6调用setForm,并且它的名称是正确的。

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

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

2 个答案:

答案 0 :(得分:2)

使用javax.faces.bean.ViewScoped时使用&#39; @ManagedBean。当您使用import javax.faces.view.ViewScoped时使用&#39; @Named如此处所述only provides the const version

答案 1 :(得分:0)

好好再挖一下后我找到了答案。这有帮助

https://stackoverflow.com/a/14813093/564045

当我切换到使用@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