MethodExpression 未在 HtmlCommandLink 中触发

2024-04-16

我有一个动态生成的数据表,像这样

    DataTable dataTable = new DataTable();
    dataTable.setValue(relatorioVOList);
    dataTable.setVar("rVO");

    Column checkBoxColumn = new Column();
    checkBoxColumn.getChildren().add(this.viewComponentBuilder.createExpressionTextWithLink("#{rVO.iRelatorio}","#{rVO.nNome}"));
    dataTable.getColumns().add(checkBoxColumn);


public HtmlForm createExpressionTextWithLink(String iRelatorioExpressionValue, String valueExpressionValue) {
    HtmlForm form = new HtmlForm();
    HtmlCommandLink link = new HtmlCommandLink();

    //config
    FacesContext context = FacesContext.getCurrentInstance(); 
    Application application = context.getApplication();
    ExpressionFactory ef = application.getExpressionFactory();
    ELContext elc = context.getELContext();

    //value that is the reports name
    ValueExpression nameValueExp = ef.createValueExpression(elc, valueExpressionValue, Object.class);
    link.setValueExpression("value", nameValueExp);

    //action that goes to method teste when link is clicked
    MethodExpression methodExpression = createMethodExpression("#{componenteC.teste(rVO.iRelatorio)}", String.class, Integer.class);
    link.setActionExpression(methodExpression);

    form.getChildren().add(link);
    return form;
}

private static MethodExpression createMethodExpression(String expression, Class<?> returnType, Class<?>... parameterTypes) {
    FacesContext facesContext = FacesContext.getCurrentInstance();
    return facesContext.getApplication().getExpressionFactory().createMethodExpression(
            facesContext.getELContext(), expression, returnType, parameterTypes);
}

在 ComponenteS(一个 RequestScoped Bean)中,testis 函数

public String teste(Integer iRelatorio) {
    System.out.println("cheguei");
    return "componente";
}

目标是 teste 函数将根据 iRelatorio 参数生成一个 url。 这里的问题是该函数从未被调用。我尝试用显式的 10“#{componenteC.teste(10)}”替换 rVO.iRelatorio,即使如此,该操作似乎也没有被触发。 报告名称显示正确。


动态创建UIInput https://docs.oracle.com/javaee/7/api/javax/faces/component/UIInput.html, UICommand https://docs.oracle.com/javaee/7/api/javax/faces/component/UICommand.html and UINamingContainer https://docs.oracle.com/javaee/7/api/javax/faces/component/UINamingContainer.html成分must有一个固定的id分配的。否则,它将得到一个自动生成的视图,该视图在恢复视图时不一定相同。组件 ID 用在提交的表单数据中的请求参数名称中,然后 JSF 将使用该组件 ID 来收集提交的输入值并在应用请求值阶段识别调用的命令。如果组件 ID 发生更改,那么 JSF 将无法按预期执行应用请求值阶段。

因此,请采取相应行动:

dataTable.setId("tableId");
// ...
form.setId("formId");
// ...
link.setId("linkId");

还有其他潜在原因,但在问题迄今为止提供的信息中看不到这些原因。为此,请花点时间仔细阅读以下有关“动态”创建组件/视图的相关答案:

  • 动态创建输入文本 https://stackoverflow.com/questions/15345349/create-inputtext-dynamically/
  • JSF 中的“绑定”属性如何工作?何时以及如何使用它? https://stackoverflow.com/questions/14911158/how-does-the-binding-attribute-work-in-jsf-when-and-how-should-it-be-used
  • 如何创建动态 JSF 表单字段 https://stackoverflow.com/questions/3510614/how-to-create-dynamic-jsf-1-2-form-fields/

也就是说,使用 XHTML 来声明和创建组件确实比使用那些混乱的 Java 代码更好。 XHTML(+XML) 更具声明性和可读性,因此更易于理解和维护。JSTL 在这方面可能非常有帮助 https://stackoverflow.com/questions/3342984/jstl-in-jsf2-facelets-makes-sense/.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MethodExpression 未在 HtmlCommandLink 中触发 的相关文章