【问题标题】:p:dataTable selected value setter doesn't workp:dataTable 选定值设置器不起作用
【发布时间】:2015-02-23 19:27:52
【问题描述】:

我是 JSF 和 PrimeFaces 的新手,我不明白为什么我的选定值的设置器没有设置:

我有主 XHTML,点击 <p:commandButton> 后我想更改选定的行。但是在更改数据设置器setSelectedBook() 上的行选择后,在入口处获取null 值。

我已经为<p:dataTable> 设置了selectionrowKey

看起来像:

主要的 XML:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
      xmlns:p="http://primefaces.org/ui"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      >

    <body>
        <ui:composition template="./../../WEB-INF/pagesTemplate.xhtml">
            <form>
                <ui:define name="content">

                    <p:dataTable id="eventsDT" var="book" value="#{bookHolder.books}"
                                 selectionMode= "single" selection="#{bookController.selectedBook}"
                                 rowKey="#{book.id}">

                        <p:ajax event="rowSelect"/>
                        <p:ajax event="rowDblselect" listener="#{bookController.onDoubleRowSelect}"  />

                        <p:column headerText="ID">
                            <h:outputText value="#{book.id}" />
                        </p:column>

                        <p:column headerText="Title">
                            <h:outputText value="#{book.longName}" />
                        </p:column>

                    </p:dataTable>
                </ui:define>

                <ui:define name="right">
                    <h:panelGrid columns="1" cellpadding="5">
                        <p:commandButton id="btnEdit" value="Edit"
                                         action="#{navigationController.moveToBookEditPageSimple}"
                                         style="width: 100px;height: 28px; margin-left: 10%"/>
                    </h:panelGrid>
                </ui:define>

            </form>
        </ui:composition>
    </body>
</html>

无法获取值的BookController:

@Named("bookController")
@SessionScoped
@Local(BookView.class)
public class BookController implements Serializable {

    public BookController() {
        navigator = new NavigationController();
    }

    NavigationController navigator;

    @Inject
    BookHolder bookHolder;

    private Book selectedBook;

    public Book getSelectedBook() {
        return selectedBook;
    }

    public void setSelectedBook(Book selectedBookValue) {
        this.selectedBook = selectedBookValue;
    }

    public void onDoubleRowSelect(SelectEvent event) throws IOException {
        String str = navigator.showPage("BookEdit");
        FacesContext.getCurrentInstance().getExternalContext().redirect(str + ".xhtml");
    }      
}

包含数据的BookHolderBean:

@Named("bookHolder")
@ApplicationScoped
public class BookHolder {

    public BookHolder() {
    }

    @PostConstruct
    void setValues() {
        this.books = new ArrayList<>();

        for (int i = 0; i < 10; i++) {
            this.books.add(new Book(new ParkType(i, i,
                    "Book #: " + i + " (long name)",
                    "Book #: " + i + " (short name)",
                    "Book #: " + i + " (note)")));

        }
    }

    private List<Book> books;

    public List<Book> getBooks() {
        return books;
    }

    public void setBooks(List<Book> parkTypes) {
        this.books = parkTypes;
    }
}

课本:

public class Book extends MainEntitie<Book> implements Serializable, SelectableDataModel<Book> {
    @Inject
    BookHolder bookHolder;

    private final String longName;
    private final String shortName;

    public Book(BookBase sd) {
        super(sd.getId(), false, false, sd.getNote());
        this.longName = sd.getLongName();
        this.shortName = sd.getShortName();
    }

    public String getLongName() {
        return longName;
    }

    public String getShortName() {
        return shortName;
    }

    @Override
    public int getId() {
        return super.getId();
    }

    @Override
    public Object getRowKey(Book t) {
        return t.getId();
    }

    @Override
    public Book getRowData(String string) {
        for (Book app : bookHolder.getBooks()) {
            if (app.getId() == Integer.parseInt(string)) {
                return app;
            }
        }
        return null;
    }
}

【问题讨论】:

  • 相当混乱的事情。你为什么不直接使用LazyDataModel&lt;T&gt;?它是SelectableDataModel&lt;T&gt; 的一种特化。为什么不使用 LazyDataModel&lt;T&gt; 扩展托管 bean 类 (BookHolder) 并使用它的 public List&lt;T&gt; load(...) 的重载版本之一?
  • 因为我只是在.net上编程后才尝试了解jsf是如何工作的,并不了解LazyDataModel。感谢您的建议,我会阅读相关信息并尝试!

标签: jsf primefaces


【解决方案1】:

由于您使用ui:define,我假设您的模板文件中有一个ui:include (pagesTemplate.xhtml)。 如果是这样,那很好,但是您包含的页面有一些不必要的东西,例如html 和 body 标签(顺便说一句:使用h:body)。没必要。

请参阅second part of this posting 了解如何将 xhtml 文件包含到另一个文件中。

您会注意到ui:define 的内容有点像“剪切和粘贴”到您的模板文件中。 那么,您的form 标签呢?它被忽略了(至少,我猜它不会是您的数据表的父级)。 使h:form(同样,使用JSF的h:form而不是HTML form)成为ui:define的孩子, 喜欢:

<ui:composition template="/WEB-INF/template.xhtml"
xmlns=.....>
   <ui:define name="content">
      <h:form>
         <p:dataTable ...>
            ...
         </p:dataTable>
      </h:form>
   </ui:define>
</ui:composition>

【讨论】:

  • 非常感谢 - 它有效!我从主要的 xhtml 标签中删除了
    和 并将 粘贴在数据表周围,setter 开始工作。
  • 合成之外的普通正文(不是 h:body)很好......即使是头部和 html 也很好,哎呀,所有 外部 合成都很好(根据 jsf 规范)例如请参阅mkyong.com/jsf2/jsf-2-templating-with-facelets-example 在组合之外使用 html/head/body 的一个原因是 IDE 有时可以更好地识别用于设计事物的文件
猜你喜欢
  • 2015-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-19
  • 2016-10-06
  • 1970-01-01
相关资源
最近更新 更多