【发布时间】:2012-09-12 10:39:09
【问题描述】:
我基于 PrimeFaces 组件创建了一个复合组件,该组件用作多行文本组件。文本被添加到输入中,单击“添加”按钮,该文本被添加到菜单中。菜单中的项目是提交的值。这工作正常,直到我将其设置为复合组件。然后,最初的“添加”单击不会添加值。随后的点击工作正常。据我所知,直到第二次单击才创建 ViewState。我认为这是问题所在。难道我做错了什么?它是一个错误吗?代码如下:
复合组件:
<cc:interface>
<cc:attribute name="value" type="java.util.Collection" />
</cc:interface>
<cc:implementation>
<p:inputText value="#{multiTextBean.text}" id="txtInput" />
<p:commandButton value="Add" action="#{multiTextBean.add}"
update="menu txtInput" />
<p:commandButton value="Clear"
action="#{multiTextBean.clear}" update="menu txtInput" />
<p:selectManyMenu id="menu"
value="#{multiTextBean.removes}">
<f:selectItems id="items"
value="#{multiTextBean.items}" />
</p:selectManyMenu>
<p:commandButton value="Remove"
action="#{multiTextBean.remove}" update="menu" />
</cc:implementation>
组件的支持类:
package util;
import java.io.IOException;
import java.util.Set;
import javax.faces.component.NamingContainer;
import javax.faces.component.UIInput;
import javax.faces.component.UISelectItems;
import javax.faces.context.FacesContext;
import javax.faces.convert.ConverterException;
import org.primefaces.component.selectmanymenu.SelectManyMenu;
public class multitext extends UIInput implements NamingContainer {
public String getFamily(){
return "javax.faces.NamingContainer";
}
@SuppressWarnings("unchecked")
@Override
protected Object getConvertedValue(FacesContext context, Object newSubmittedValue)
throws ConverterException {
SelectManyMenu menu = (SelectManyMenu) findComponent("menu");
UISelectItems items = (UISelectItems) menu.findComponent("items");
Set<String> localItems = (Set<String>) items.getValue();
return localItems;
}
@Override
public Object getSubmittedValue() {
return this;
}
@Override
public void encodeBegin(FacesContext context) throws IOException {
super.encodeBegin(context);
}
}
复合组件引用的Bean
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
@ManagedBean
@ViewScoped
public class MultiTextBean {
private String text;
private Set<String> items;
private List<String> removes;
@PostConstruct
public void init(){
items = new HashSet<String>();
removes = new ArrayList<String>();
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public Set<String> getItems() {
return items;
}
public List<String> getRemoves() {
return removes;
}
public void setRemoves(List<String> removes) {
this.removes = removes;
}
public void add(){
if(!text.isEmpty())
{items.add(text);}
text = null;
}
public void clear(){
items.removeAll(items);
text = null;
}
public void remove(){
items.removeAll(removes);
}
}
组件看起来像:
使用本测试页上的组件:
<!DOCTYPE html>
<html lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:mt="http://java.sun.com/jsf/composite/util"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Insert title here</title>
</h:head>
<h:body>
<ui:debug hotkey="x"/>
<form>
<mt:multitext value="#{backingBean.submittedValues}"/>
<p:commandButton value="Submit" action="Submit" update="@all" process="@all"/>
#{backingBean.submittedValues}
</form>
</h:body>
</html>
【问题讨论】:
-
您是否事先使用
<f:ajax>从另一个表单呈现包含复合材料的表单?然后可能会发生表单将失去其视图状态。另见stackoverflow.com/questions/7807334/… -
@BalusC 不。我已经用我用来运行测试的 xhtml 页面更新了问题。这看起来好吗?
-
另外,@BalusC 根据您的博客,我认为使用 PrimeFaces 组件时该错误无关紧要。是吗?
-
这适用于打开/更新表单的方式。不是打开/更新的表单本身包含哪些组件。
-
@BalusC 好吧,我只有一个表格,所以我认为这是一个不同的问题。
标签: java jsf jsf-2 primefaces