【问题标题】:Using @ManageProperty and datatable var "currentRow"使用 @ManageProperty 和数据表 var "currentRow"
【发布时间】:2011-08-31 18:35:45
【问题描述】:

我有一个视图范围的 bean ManageFoo.java:

@ManagedBean(name = "ManageFoo")
@ViewScoped
public class ManageFoo {

  @ManagedProperty(value = "#{currentRow}")
  private Foo currentRowBean;
  .
  .
  public void setCurrentRowBean(Foo foo) {...}
  public Foo getCureentRowBean() {...}

  public void edit(ActionEvent e) {
    getCurrentRowBean();
    .
    .
  }
}

然后我有 facelets 文件 ManageFoo.xhtml:

<h:dataTable value=#{ManageFoo.foos} var="currentRow">
  <h:column>
    <h:commandLink actionListener="#{ManageFoo.edit}"/>
.
.

但是,当单击“commandLink”时,“getCurrentRowBean”返回 null。

我使用 FacesContext 和 getBean("currentRow") 辅助方法可以正常工作,但我正在尝试通过使用 ManagedProperty、ManagedBean 等来“JSF 2ify”我的 Web 应用程序。我只是没有正确实现它还是我是否试图以没有意义的方式使用 ManageProperty?

根据 Balus 的反馈,他的解决方案适用于我的操作方法,但我无法让它适用于返回值的方法(例如布尔值)。以下方法用于每一行的一堆“渲染”属性。例如,如果您正在编辑某一行,则其他行上的所有其他编辑按钮都会消失,并且当前行的编辑按钮会被取消编辑按钮和保存按钮所取代。所以,这个方法每一行的​​返回结果都不一样:

public boolean isCurrentRowEditing() {
    if(getCurrentRowDataBean().equals(getCurrentDataEditing())) {
        return true;
    } else {
        return false;
    }
}

由于我试图在任何地方消除“getCurrentRowDataBean()”方法,我需要一种方法来实现它。

【问题讨论】:

    标签: jsf jsf-2


    【解决方案1】:

    @ManagedProperty 是在 bean 构造之后直接设置的。在构建 bean 时,JSF 肯定不会忙于遍历数据表。此外,您的 bean 被置于视图范围内,因此它是在第一次请求视图时设置的,而不是在您将表单提交到同一视图时设置的。 #{currentRow} 将始终为 null

    有几种方法可以实现这一点。如果您正在运行支持 EL 2.2 的容器或使用 JBoss EL,那么您可以将其传递给操作(而不是侦听器!)方法:

    <h:commandLink action="#{manageFoo.edit(currentRow)}"/>
    

    (请注意,我将您的托管 bean 名称固定为以小写开头,符合编码约定)

    public void edit(Foo currentRow) {
        // ...
    }
    

    如果您没有运行支持 EL 2.2 的容器,也不能使用 JBoss EL,那么您需要将数据表的值绑定到 DataModel 并在 action(listener) 方法中使用 DateModel#getRowData() 来获取当前行。

    另见:


    更新根据您的更新,只需在 EL 中进行比较。例如

    rendered="#{currentRow == manageFoo.currentRow}"
    

    rendered="#{currentRow != manageFoo.currentRow}"
    

    (请注意,这只有在其 equals() 正确实现时才有效!)

    【讨论】:

    • 我会试试这个...我正在使用 Glassfish 3,所以我几乎可以肯定它会使用最新的 EL 版本。后续问题:那么,您如何访问 'edit' 方法中的 'currentRow' 变量?
    • 如果您的web.xml 被声明为符合Servlet 3.0,那么EL 2.2 肯定可以工作。操作方法很简单。我在答案中添加了一个示例以及一系列相关问题的链接以及 EL 2.2 和DataModel 方式的更详细示例。
    • 谢谢巴鲁斯。到现在为止还挺好。但是我在整个 Bean 中还有“currentRow”的其他用途……不仅仅是在动作方法中。例如,我有一个“isEditingCurrentRow”方法,它也使用 getCurrentRowBean。看起来你不能将变量传递给它,因为你可以传递一个动作方法。有什么想法吗?
    • 让动作方法委托。例如。 this.currentRow = currentRow;doSomethingWith(currentRow);。顺便说一句,您真的没有阅读 CRUD 示例链接吗? :) 它包含触发“编辑模式”的示例。您也可以只做rendered="#{not empty bean.currentRow}" 以显示编辑部分。
    • CRUD 链接当然看起来很有价值……下次我编写 CRUD 应用程序时。不幸的是,我只是想重写一点我的代码......不是全部!我不确定委派是否会起作用,因为每一行都会检查 isEditingCurrentRow 以进行不同的渲染。它将 currentRow 与正在编辑的行进行比较,如果它们相同,则返回 true(否则返回 false)。所以,isEditingCurrentRow 实际上需要以某种方式接收一个变量。
    猜你喜欢
    • 2012-02-07
    • 2022-08-03
    • 2023-04-08
    • 1970-01-01
    • 1970-01-01
    • 2010-11-20
    • 2019-11-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多