Using @ManageProperty and datatable var "currentRow"
I have a view-scoped 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();
.
.
}
}
I then have the facelets file ManageFoo.xhtml:
<h:dataTable value=#{ManageFoo.foos} var="currentRow">
<h:column>
<h:commandLink actionListener="#{ManageFoo.edit}"/>
.
.
When the 'commandLink' is clicked, however, 'getCurrentRowBean' returns null.
I have this working fine using FacesContext and a getBean("currentRow") helper method, but I'm trying to "JSF 2ify" my web application by using ManagedProperty's, ManagedBean's, etc. Am I just not implementing this properly or am I trying to use ManageProperty's in a way that doesn't make sense?
After feedback from Balus, his solution works well for my action methods, but I'm having trouble getting it to work for methods that return values (such as boolean). The following method is used in a bunch of "rendered" attributes for each row. For example, if you are editing a certain row, all of the other edit buttons on the other rows disappear and the edit button for the current row is replaced by a cancel edit button and save button. So, this method has different return results for each row:
public boolean isCurrentRowEditing() {
if(getCurrentRowDataBean().equals(getCurrentDataEditing())) {
开发者_开发知识库 return true;
} else {
return false;
}
}
Since I'm trying to eliminate the "getCurrentRowDataBean()" method everywhere, I need a way for this to work.
The @ManagedProperty
is set directly after bean's construction. At the point the bean is been constructed, JSF is definitely not busy iterating over the datatable. Also, your bean is put in view scope, so it's been set when the view is requested for the first time, not when you submit the form to the same view. The #{currentRow}
will always be null
.
There are several ways to achieve this. If you're running an EL 2.2 capable container or are using JBoss EL, then you could just pass it to the action (not listener!) method:
<h:commandLink action="#{manageFoo.edit(currentRow)}"/>
(note that I fixed your managed bean name to start with lowercase, conform the coding conventions)
with
public void edit(Foo currentRow) {
// ...
}
If you aren't running an EL 2.2 capable container nor can't use JBoss EL, then you need to bind the datatable's value to DataModel
and use DateModel#getRowData()
inside the action(listener) method to obtain the current row.
See also:
- How can I pass selected row to commandLink inside dataTable? (shows all possible ways)
- Recommended JSF 2.0 CRUD frameworks (shows
DataModel
way) - Update backing bean in datatable from h:commandButton and JPA (shows EL 2.2 way)
Update as per your update, just compare it in EL. E.g.
rendered="#{currentRow == manageFoo.currentRow}"
and
rendered="#{currentRow != manageFoo.currentRow}"
(note that this only works if its equals()
is properly implemented!)
精彩评论