我创建了一个基于 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>