Как можно условно выбрать тип ввода html в стандартной таблице данных JSF без накладных расходов на неотрисованные компоненты? У меня есть решение, но этого недостаточно для меня.
Пример тестового компонента:
@Named
@ViewScoped
public class TestBean implements Serializable {
private static final long serialVersionUID = 1L;
private Map<Descriptor, Object> values = new HashMap<>();
public TestBean() {
values.put(new Descriptor("Integer value", "Integer"), 10);
values.put(new Descriptor("String value", "String"), "example string");
values.put(new Descriptor("Boolean value", "Boolean"), Boolean.TRUE);
}
public Map<Descriptor, Object> getValues() {
return values;
}
public class Descriptor implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private String type;
public Descriptor(String name, String type) {
this.name = name;
this.type = type;
}
public String getName() {
return name;
}
public String getType() {
return type;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || !TestBean.class.equals(o.getClass())) {
return false;
}
Descriptor other = (Descriptor) o;
return Objects.equals(name, other.name) &&
Objects.equals(type, other.type);
}
@Override
public int hashCode() {
return Objects.hash(name, type);
}
}
}
Пример test.xhtml part1:
<!-- Works -->
<h:dataTable value="#{testBean.values.keySet()}" var="valueKey">
<h:column>
<f:facet name="header">Key</f:facet>
<h:outputText value="#{valueKey.name}"/>
</h:column>
<h:column>
<f:facet name="header">Value</f:facet>
<h:inputText pt:type="number" pt:step="1" converter="javax.faces.Integer"
value="#{testBean.values[valueKey]}" rendered="#{valueKey.type eq 'Integer'}"/>
<h:selectBooleanCheckbox value="#{testBean.values[valueKey]}" rendered="#{valueKey.type eq 'Boolean'}"/>
<h:inputTextarea value="#{testBean.values[valueKey]}"
rendered="#{valueKey.type ne 'Integer' and valueKey.type ne 'Boolean'}"/>
</h:column>
</h:dataTable>
Таким образом, все работает правильно, но я утроил количество компонентов для одного входа. (Неотображенные компоненты все еще добавляются в дерево компонентов.) Это неприемлемо, поскольку мне приходится работать с большим набором данных. В случае большого количества записей время отклика очень медленное. Так что я ищу другой способ, как пример ниже:
Пример test.xhtml part2:
<!-- Doesn't work -->
<h:dataTable value="#{testBean.values.keySet()}" var="valueKey">
<h:column>
<f:facet name="header">Key</f:facet>
<h:outputText value="#{valueKey.name}"/>
</h:column>
<h:column>
<f:facet name="header">Value</f:facet>
<c:choose>
<c:when test="#{valueKey.type eq 'Integer'}">
<h:inputText pt:type="number" pt:step="1" converter="javax.faces.Integer"
value="#{testBean.values[valueKey]}"/>
</c:when>
<c:when test="#{valueKey.type eq 'Boolean'}">
<h:selectBooleanCheckbox value="#{testBean.values[valueKey]}"/>
</c:when>
<c:otherwise>
<h:inputTextarea value="#{testBean.values[valueKey]}"/>
</c:otherwise>
</c:choose>
</h:column>
</h:dataTable>
Это было бы здорово, но значение атрибута test на момент сборки представления равно нулю.
Есть ли обходной путь для уменьшения числа компонентов, когда мне нужен оператор switch внутри dataTable? Другими словами: как я могу достичь результата первого примера без дополнительных (не обработанных) компонентов в дереве компонентов?
(я работаю с Моджаррой 2.2.8-17)