我想了解如何对复合组件进行编程,并且已经通过balusc和其他方法跟踪了很好的例子,但我错过了一些东西。为什么我不能在复合组件中的encodeBegin中设置f:selectItems?
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:c="http://java.sun.com/jstl/core"
xmlns:cc="http://java.sun.com/jsf/composite">
<cc:interface componentType="simpleComponent">
<cc:attribute name="value" required="true" type="example.LanguageDefinition"/>
<cc:attribute name="possibilities" default="de_DE" type="java.lang.String"/>
</cc:interface>
<cc:implementation>
<p:selectOneMenu binding="#{cc.inputComponent}" converter="omnifaces.SelectItemsConverter" var="l"
value="#{cc.attrs.value}">
<p:ajax update="@form"/>
<f:selectItems value="#{cc.languages}" var="l" itemLabel="#{l.label}"
itemValue="#{l}" />
<p:column>#{l.label}</p:column>
<p:column>
<p:graphicImage name="#{l.imgPath}" />
</p:column>
</p:selectOneMenu>
</cc:implementation>
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.faces.component.FacesComponent;
import javax.faces.component.NamingContainer;
import javax.faces.component.UIInput;
import javax.faces.component.UINamingContainer;
import javax.faces.context.FacesContext;
import example.LanguageDefinition;
@FacesComponent("simpleComponent")
public class SimpleComponent extends UIInput implements NamingContainer {
private UIInput inputComponent;
public UIInput getInputComponent() {
return inputComponent;
}
public void setInputComponent(UIInput inputComponent) {
this.inputComponent = inputComponent;
}
@Override
public Object getSubmittedValue() {
return inputComponent.getSubmittedValue();
}
@Override
protected Object getConvertedValue(FacesContext context, Object newSubmittedValue) {
return (String) newSubmittedValue;
}
@Override
public String getFamily() {
return UINamingContainer.COMPONENT_FAMILY;
}
@Override
public void encodeBegin(FacesContext context) throws IOException {
String possibilities = getAttributeValue("possibilities", "en_US");
// In theory, build based on incoming possibilities, now hard code
List<LanguageDefinition> languages = new ArrayList<LanguageDefinition>();
languages.add(new LanguageDefinition("pt_PT",
"images/flags/PT.gif", "Português (Portugal)"));
languages.add(new LanguageDefinition("cs_CZ",
"images/flags/CZ.gif", "Czech (Czech Republic)"));
getStateHelper().put("languages", languages);
super.encodeBegin(context);
}
@SuppressWarnings("unchecked")
public List<LanguageDefinition> getLanguages() {
return (List<LanguageDefinition>) getStateHelper().get("languages");
}
/**
* Return specified attribute value or otherwise the specified default if it's null.
*/
@SuppressWarnings("unchecked")
private <T> T getAttributeValue(String key, T defaultValue) {
T value = (T) getAttributes().get(key);
return (value != null) ? value : defaultValue;
}
}
这是行不通的调用是这样的:
<ex:simpleComponent value="#{compBean.selected}"/>
一切都呈现正常,但提交值永远不会回传给我的 “compBean”。但是,如果我不是在encodeBegin它做其他任何其他方式设置selectItems的“语言”的作品......与getter和setter方法,或者使用此代码的一个成员变量:
<c:set target="#{cc}" property="possibilities" value="#{cc.attrs.possibilities}"/>
在组合这种更简单的类:
import java.util.ArrayList;
import java.util.List;
import javax.faces.component.FacesComponent;
import javax.faces.component.NamingContainer;
import javax.faces.component.UIInput;
import javax.faces.component.UINamingContainer;
import example.LanguageDefinition;
@FacesComponent("simpleComponent")
public class SimpleComponent extends UIInput implements NamingContainer {
@Override
public String getFamily() {
return UINamingContainer.COMPONENT_FAMILY;
}
public void setPossibilities(String possibilities) {
if (getStateHelper().get("possibilities") == null) {
List<LanguageDefinition> languages = new ArrayList<LanguageDefinition>();
languages.add(new LanguageDefinition("pt_PT",
"images/flags/PT.gif", "Português (Portugal)"));
languages.add(new LanguageDefinition("cs_CZ",
"images/flags/CZ.gif", "Czech (Czech Republic)"));
getStateHelper().put("languages", languages);
getStateHelper().put("possibilities", possibilities);
}
}
public String getPossibilities() {
return (String) getStateHelper().get("possibilities");
}
@SuppressWarnings("unchecked")
public List<LanguageDefinition> getLanguages() {
return (List<LanguageDefinition>) getStateHelper().get("languages");
}
}
但是,这似乎并没有权利做这种方式(不是balusc的方式做到了),所以我只是想了解。哪种方法更好?假设第一个,我为什么不工作?
谢谢!