在 table 中以编程方式创建的 JSF commandLink 不起作用
JSF commandLink created programmatically inside table doesn't work
这可能吗?经过几个小时的战斗我放弃了。
JSF table 是以编程方式创建的,内部也有 commandLinks。
下面一段代码在 table 的外部和内部带有 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 bean:
@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]);
}
}
table 中的链接已创建,但不起作用。
在 table 之外创建的那个也以编程方式创建的工作正常。
有什么想法吗?
简要说明
您在上面遇到的问题是由于视图处理程序 无法 处理您的操作 link 因为它无法为 link 组件 - 意味着实际上缺少对激活组件的引用。
你举的两个例子其实都不对。然而,由于 link 在 table 之外生成,视图处理程序能够以某种方式找出组件的 id,并在执行操作时在正确的位置结束。
看代码
如果我们查看调用上述代码时 JSF Mojarra 生成的内容,我们可以看到以下内容:
table 中的 link 得到一个 link 到 form:j_idt3:0:j_id3
但没有 id 归于组件,所以 link 将不行。
table外面的link得到一个link到form:j_idt5
,生成idj_id1:javax.faces.ViewState:0
。因此,虽然它确实调用了操作 - link/id 相关性并不完全正确。
很明显,渲染器能够为 link 计算出生成的 ID,但它从未将生成的 ID 设置到实际的 component/tag 上。这有点问题。
解决问题
这里的解决方案是帮助 JSF 和视图处理程序找出带有操作的组件的路径。您可以通过在以编程方式生成命令 link 时强制设置 id 来执行此操作 - 在 getTable()
方法中,添加以下代码;
inlink.setId("link");
这应该允许呈现器呈现具有工作操作的有效页面 links。
这可能吗?经过几个小时的战斗我放弃了。
JSF table 是以编程方式创建的,内部也有 commandLinks。
下面一段代码在 table 的外部和内部带有 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 bean:
@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]);
}
}
table 中的链接已创建,但不起作用。 在 table 之外创建的那个也以编程方式创建的工作正常。
有什么想法吗?
简要说明
您在上面遇到的问题是由于视图处理程序 无法 处理您的操作 link 因为它无法为 link 组件 - 意味着实际上缺少对激活组件的引用。
你举的两个例子其实都不对。然而,由于 link 在 table 之外生成,视图处理程序能够以某种方式找出组件的 id,并在执行操作时在正确的位置结束。
看代码
如果我们查看调用上述代码时 JSF Mojarra 生成的内容,我们可以看到以下内容:
table 中的 link 得到一个 link 到 form:j_idt3:0:j_id3
但没有 id 归于组件,所以 link 将不行。
table外面的link得到一个link到form:j_idt5
,生成idj_id1:javax.faces.ViewState:0
。因此,虽然它确实调用了操作 - link/id 相关性并不完全正确。
很明显,渲染器能够为 link 计算出生成的 ID,但它从未将生成的 ID 设置到实际的 component/tag 上。这有点问题。
解决问题
这里的解决方案是帮助 JSF 和视图处理程序找出带有操作的组件的路径。您可以通过在以编程方式生成命令 link 时强制设置 id 来执行此操作 - 在 getTable()
方法中,添加以下代码;
inlink.setId("link");
这应该允许呈现器呈现具有工作操作的有效页面 links。