我的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;
}
}
正如您在下面的屏幕截图中看到的那样初始化的初始表单显示正常,但添加带有名称的表单只会呈现一个没有标题的新标签
我所做的是在Form.setName中放置一个断点,在FormController.createForm中放置一个断点。
键入表单名称并单击“添加表单”时,将调用这两种方法。
首先使用Form对象引用(例如)com.test.Form@30998fa6调用setForm,并且它的名称是正确的。
然后使用Form对象引用com.test.Form@2ad84d0f调用createForm,名称为null。我不明白的是为什么这些显然是两种不同的形式对象。
另一个症状是多次调用@PostConstruct而不是一次。
答案 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