Это возможно? После нескольких часов боя я сдаюсь.
Таблица JSF создается программно, а внутри commandLinks.
Ниже фрагмент кода с commandLink снаружи и внутри таблицы. Оба создаются аналогичным образом. Полный код XHTML:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns = "http://www.w3.org/1999/xhtml" xmlns:h = "http://java.sun.com/jsf/html" xmlns:f = "http://java.sun.com/jsf/core">
<f:view contentType = "text/html" locale = "pl">
<h:body>
<h:form id = "form">
<h:dataTable binding = "#{dynamicDataTable.table}" value = "#{dynamicDataTable.tableContent}" />
<!-- this one below works fine -->
<h:commandLink binding = "#{dynamicDataTable.link}" />
</h:form>
</h:body>
</f:view>
</html>
Бин DynamicDataTable:
@Named
@ViewScoped
public class DynamicDataTable implements Serializable {
private static final long serialVersionUID = 1L;
private HtmlDataTable table;
private HtmlCommandLink link;
private List<String> tableContent;
public void action() {
System.out.println("Action performed");
}
public HtmlDataTable getTable() {
table = new HtmlDataTable();
HtmlCommandLink inlink = new HtmlCommandLink();
inlink.setValue("Inside link");
inlink.setActionExpression(createMethodExpression("#{dynamicDataTable.action}", String.class));
UIColumn column = new UIColumn();
column.getChildren().add(inlink);
table.getChildren().add(column);
return table;
}
public List<String> getTableContent() {
tableContent = new ArrayList<String>();
tableContent.add("a");
tableContent.add("b");
return tableContent;
}
public void setTableContent(List<String> tableContent) {
this.tableContent = tableContent;
}
public void setTable(HtmlDataTable table) {
this.table = table;
}
public HtmlCommandLink getLink() {
link = new HtmlCommandLink();
link.setValue("Outside link");
link.setActionExpression(createMethodExpression("#{dynamicDataTable.action}", String.class));
return link;
}
public void setLink(HtmlCommandLink link) {
this.link = link;
}
public static MethodExpression createMethodExpression(String expression, Class<?> returnType) {
FacesContext context = FacesContext.getCurrentInstance();
return context.getApplication().getExpressionFactory().createMethodExpression(
context.getELContext(), expression, returnType, new Class[0]);
}
}
Ссылки внутри таблицы создаются, но не работают. Созданный вне таблицы, также созданный программно, отлично работает.
Любая идея?
@AdamWaldenberg Я обновил свой пример с полным минимальным кодом
Я посмотрю.
Проблема, с которой вы столкнулись выше, вызвана тем фактом, что обработчик представления имеет значение не могущий для обработки вашей ссылки действия, потому что он не может сгенерировать идентификатор для компонента ссылки, что означает, что ссылка на активированный компонент фактически отсутствует.
Оба ваших примера на самом деле не совсем верны. Однако со ссылкой, сгенерированной вне таблицы, обработчик представления каким-то образом может определить идентификатор компонента и оказывается в нужном месте при выполнении действия.
Если мы посмотрим на то, что генерирует JSF Mojarra, когда мы вызываем приведенный выше код, мы увидим следующее:
Ссылки внутри таблицы получают ссылку на form:j_idt3:0:j_id3
, но компоненту не присвоен идентификатор, поэтому ссылка не будет работать.
Ссылка вне таблицы получает ссылку на form:j_idt5
, и генерируется идентификатор j_id1:javax.faces.ViewState:0
. Таким образом, хотя он действительно вызывает действие, корреляция ссылка/идентификатор не совсем верна.
Таким образом, ясно, что рендерер может определить сгенерированный идентификатор для ссылки, но он никогда не устанавливает этот сгенерированный идентификатор на фактический компонент/тег. Это некоторая проблема.
Решение здесь состоит в том, чтобы помочь JSF и обработчику представления выяснить путь к компоненту с действием. Вы можете сделать это, принудительно установив идентификатор при программном создании командной ссылки — внутри метода getTable()
добавьте следующий код;
inlink.setId("link");
Это должно позволить средству визуализации отображать действительную страницу с рабочими ссылками действий.
Спасибо, это действительно решило проблему (по крайней мере, с h: commandLink). Когда я превратился в Primefaces - он снова не работает. Может из-за включенного ajax. Я постараюсь решить это. Это была отличная поддержка, спасибо.
В конце концов, это также зависит от того, как вы используете и вызываете это. Предоставьте что-нибудь поддающееся тестированию/проверке в соответствии с минимальный воспроизводимый пример.