У меня есть databale на index.xhtml
<h:dataTable style="border: solid 2px black;"
value="#{IndexBean.bookList}" var="item"
binding="#{IndexBean.datatableBooks}">
<h:column>
<h:commandButton value="Edit" actionListener="#{IndexBean.editBook}">
<f:param name="index" value="#{IndexBean.datatableBooks.rowIndex}"/>
</h:commandButton>
</h:column>
</h:dataTable>
Мой боб:
@ManagedBean(name="IndexBean")
@ViewScoped
public class IndexBean implements Serializable {
private HtmlDataTable datatableBooks;
public HtmlDataTable getDatatableBooks() {
return datatableBooks;
}
public void setDatatableBooks(HtmlDataTable datatableBooks) {
this.datatableBooks = datatableBooks;
}
public void editBook() throws IOException{
int index = Integer.parseInt(FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("index").toString());
System.out.println(index);
}
}
Моя проблема состоит в том, что я всегда получаю тот же индекс в журнале сервера даже при том, что я нажимаю различные кнопки редактирования. Предположите, что существует один набор, который предоставляется таблице данных. Я не показал это в бобе.
Если я изменяю объем от ViewScope до RequestScope, он хорошо работает. С чем может быть проблема @ViewScoped
? Заранее спасибо :)
Править:
<h:column>
<h:commandButton value="Edit" actionListener="#{IndexBean.editBook}" />
</h:column>
public void editBook(ActionEvent ev) throws IOException{
if (ev.getSource() != null && ev.getSource() instanceof HtmlDataTable) {
HtmlDataTable objHtmlDataTable = (HtmlDataTable) ev.getSource();
System.out.println(objHtmlDataTable.getRowIndex());
}
}
Вы уже связали компонент
с компонентом.Все, что вам нужно сделать, это:
public void editBook() throws IOException{
int index = datatableBooks.getRowIndex(); // Actually not interesting info.
Book book = (Book) datatableBooks.getRowData(); // This is what you want.
}
здесь также не нужен. Дополнительные подсказки можно найти также в этой статье .
Обновление : я могу воспроизвести вашу проблему. Скорее всего, это ошибка @ViewScoped
. Когда bean-компонент установлен на @RequestScoped
, он работает должным образом. Кроме того, когда вы удаляете привязку компонента и самостоятельно получаете компонент из корневого каталога просмотра, он работает должным образом. Я подал по этому поводу выпуск 1658 .
Что вы можете сделать, так это использовать метод [getRowData()][1]
на Java bean, чтобы напрямую получить объект, расположенный на строке, где находится кнопка, на которую нажал пользователь.
Пример кода:
public void editBook(ActionEvent evt) {
// We get the table object
HtmlDataTable table = getParentDatatable((UIComponent) evt.getSource());
// We get the object on the selected line.
Object o = table.getRowData();
// Eventually, if you need the index of the line, simply do:
int index = table.getRowIndex();
// ...
}
// Method to get the HtmlDataTable.
private HtmlDataTable getParentDatatable(UIComponent compo) {
if (compo == null) {
return null;
}
if (compo instanceof HtmlDataTable) {
return (HtmlDataTable) compo;
}
return getParentDataTable(compo.getParent());
}
Теперь код JSF выглядит так:
<h:commandButton value="Edit" actionListener="#{IndexBean.editBook}"/>
Кроме того, не забудьте изменить сигнатуру метода editBook()
, установив аргумент javax.faces.event.ActionEvent
.