我在像这样的可编辑数据表中使用Primefaces selectManyCheckbox。当用户单击编辑按钮时,他可以在"文档"列中的不同文档之间进行选择。这是我的密码。请注意我使用的转换器:
<p:dataTable id="tbl" styleClass="fixedLayoutTable no-highlight dblclick-edit edit-commit-others"
value="#{cc.attrs.manager.mg}" var="mg"
emptyMessage="#{msgs.noManager}" editable="true" widgetVar="tbl">
<p:column headerText="Documents">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{msgs.noDocs}" rendered="#{mg.docs.size() == 0}" />
<h:outputText value="#{mg.docs.toArray()[0].fileName}" rendered="#{mg.docs.size() > 0}" />
</f:facet>
<f:facet name="input">
<p:selectManyCheckbox id="chkDoc"
value="#{mg.docs}" layout="pageDirection"
converter="myConverter" collectionType="java.util.HashSet">
<f:selectItems value="#{cc.attrs.manager.docs}"
var="d" itemValue="#{d}" itemLabel="#{d.fileName}" />
</p:selectManyCheckbox>
</f:facet>
</p:cellEditor>
</p:column>
</p:dataTable>
在应用程序的另一个选项卡(我们称之为Tab1)中,用户可以上传一些文档。这些文档已添加到backingbean中的cc.attrs.manager.docs
-List中,但尚未在数据库中持久化。如果用户在Tab1中上传一些文档并转到Tab2(带有数据表的选项卡),他应该能够在所有文档之间进行选择,包括最近添加的文档。因此,用户单击编辑按钮,所有文档都会显示在SelectManyCheckbox中。如果用户选择这些文档并单击✔-Sign my Converter被调用。
我用这个例子来实现转换器。这是此类的代码段:
@FacesConverter(value="myConverter")
public class MyConverter implements Converter {
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
if (component instanceof PickList) {
return getAsObject((PickList)component, value);
} else {
return SelectItemsUtils.findValueByStringConversion(context, component, value, this);
}
}
}
在用户不检查最近添加的文档之前,这一切都很正常。如果他检查了其中一个新文档,则getAsObject-
方法的字符串参数为"null"。有人有什么建议吗?为什么这个参数为空?是因为文档尚未持久化吗?是否可以在不持久化Tab1中添加的文档的情况下实现这一点?
不要使用您自己的自定义converter
,而是使用适用于所有内容的generic converter
。
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;
import java.util.WeakHashMap;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
@FacesConverter(value = "entityConverter")
public class EntityConverter implements Converter {
private static Map<Object, String> entities = new WeakHashMap<Object, String>();
@Override
public String getAsString(FacesContext context, UIComponent component, Object entity) {
synchronized (entities) {
if (!entities.containsKey(entity)) {
String uuid = UUID.randomUUID().toString();
entities.put(entity, uuid);
return uuid;
} else {
return entities.get(entity);
}
}
}
@Override
public Object getAsObject(FacesContext context, UIComponent component, String uuid) {
for (Entry<Object, String> entry : entities.entrySet()) {
if (entry.getValue().equals(uuid)) {
return entry.getKey();
}
}
return null;
}
}
我通过实现另一个转换器来解决这个问题,该转换器扩展EntityConverter并检查ID是否为null。这是我的代码:
@FacesConverter(value = "anotherConverter")
public class AnotherConverter extends EntityConverter {
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
if (value instanceof Document && ((Document) value).getId() == null) {
return String.valueOf(((Document) value).hashCode());
}
return super.getAsString(context, component, value);
}
}