JSF 2: h: ссылка и getrowdata - PullRequest
       29

JSF 2: h: ссылка и getrowdata

2 голосов
/ 07 апреля 2011

Если у меня есть h:dataTable in books.xhtml , предоставляющий список записей, и я хочу просмотреть определенную запись, затем добавьте или отредактируйте эту запись, в настоящее время у меня есть это:

<h:dataTable #{BookBean.books}" var="books">
   <h:link outcome="bookview" value="#{books[1]}">
      <f:param name="id" value="#{books[2]}" />
   </h:link>
</h:dataTable>

Я обнаружил, что мне нужно включить <f:param>, чтобы показать CSS-статус нажатой ссылки; в противном случае, если у меня нет <f:param>, каждый раз, когда я нажимаю на ссылку, отображаемую тегами h: link в приведенных выше кодах, все ссылки переходят в статус щелчка CSS.

Кроме того, я где-то читал о getrowdata(), но я не смог заставить его работать. Это лучшая альтернатива использованию <f:param>?

Я попробовал метод getrowdata() в своем классе BookBean следующим образом:

private DataModel<BookModel> books;
private BookModel currentBook;

public String view()
{
     currentBook = books.getRowData();
     return "bookview";
}

и в bookview.xhtml у меня есть это:

<h:dataTable value="#{BookBean.view}" var="item">
    ... // render content here
<h:dataTable>

но я получаю сообщение об ошибке, свойство не найдено. Извините за вопрос, но я все еще не понимаю некоторые из мощных функций JSF 2. Может ли какой-нибудь эксперт, который понимает использование h:link и getrowdata, объяснить мне в терминах непрофессионала или, возможно, с некоторым базовым кодом пример. Спасибо.

UPDATE: Изменены классы на основе предложений @BalusC ниже. BookModel класс:

@Entity
public class BookModel implements Serializable
{
   private Long id;
   private String title;
   private String author;   

   // getters and setters here
 }

Класс BookService выглядит следующим образом:

@Stateless
public class BookService
{
    @PersistenceContext(unitName = "persistentUnit")
    protected EntityManager entityManager;

    public BookModel create() {
       return new BookModel();
    }

    public void delete(BookModel bookModel) {
       bookModel = entityManager.merge(bookModel);
       entityManager.remove(bookModel);
    }

    public BookModel update(BookModel bookModel) {
       return entityManager.merge(bookModel);
    }

    public BookModel find(Long id) {
       return entityManager.find(BookModel.class, id);
    }
}

BookBean класс:

@ManagedBean(name = "bookBean")
@RequestScoped
public class BookBean implements Serializable
{
    @EJB
    private BookService bookService;

    @ManagedProperty(value = "#{param.id}")
    private Long id;

    private DataModel<BookModel> books;
    private BookModel currentBook;

    @PostConstruct
    public void init() {
        currentBook = bookService.find(id);
    }

    public BookModel getCurrentBook() {
       return currentBook;
    }

    public void setCurrentBook(BookModel currentBook) {
       this.currentBook = currentBook;
    }
 }

Запуск вышеуказанного класса BookBean вызвал эту ошибку: java.lang.IllegalStateException: WEB9031: WebappClassLoader unable to load resource [org.apache.openjpa.util.LongId], because it has not yet been started, or was already stopped. Вот где я застрял на данный момент.

К вашему сведению: моя среда разработки - Glassfish 3.1, Apache OpenJPA 2.1 и JSF 2.1.0 (поставляется в комплекте со Glassfish)

1 Ответ

3 голосов
/ 08 апреля 2011

В коде есть два недостатка:

  • h:link запускает запрос GET, а не запрос POST. DataModel#getRowData() здесь также бесполезен, поскольку вы не можете прикрепить действия компонента к компонентам, которые запускают запрос GET.

  • <h:dataTable value="#{BookBean.view}"> с public String view() не имеет смысла. Значение таблицы данных должно быть набором элементов, а не методом действия компонента.


Я понимаю, что вам нужна ссылка GET для каждого элемента книги в таблице, которая указывает на некоторую страницу сведений об элементе книги. Исправьте страницу сведений следующим образом:

bookview.xhtml

<h:outputText value="#{bookBean.currentBook.id}" />
<h:outputText value="#{bookBean.currentBook.author}" />
<h:outputText value="#{bookBean.currentBook.title}" />
...

И BookBean следующим образом:

@ManagedBean
@RequestScoped
public BookBean {

    @ManagedProperty(value="#{param.id}")
    private Long id;

    private BookModel currentBook;

    @PostConstruct 
    public void init() {
        currentBook = bookDAO.find(id);
    }

    // ...
}

@ManagedProperty установит параметр запроса GET. @PostConstruct предварительно загрузит нужную книгу на основе параметра.

Обратите внимание, что это не имеет ничего общего с шаблоном POST-Redirect-GET.

...