<h:link> 对比 <h:commandLink> 在 <h:dataTable>
<h:link> vs <h:commandLink> in <h:dataTable>
当我想查看我的书的详细信息页面时,我会拿到我的书并将其重定向到我的概览页面。现在,当我使用 <h:link>
时,他总是给出我的数据表的最后一项。当我使用 <h:commandLink>
时,一切正常。现在我的问题是,为什么 <h:link outcome="...">
不工作,而 <h:commandLink>
中的 'same' 代码可以工作?
托管 Bean
@Named(value = "bookController")
@SessionScoped
public class BookController implements Serializable {
@EJB private BookRepository dao;
private LibraryBook book = new LibraryBook();
...
public String getLibraryBook(String isbn)
{
this.book = this.dao.getBook(isbn);
return "bookOverview";
}
...
}
Book.xhtml
<f:view>
<h:form>
<h:dataTable value="#{bookController.books}" var="item" class="table">
<h:column>
<f:facet name="header">
<h:outputText value="Isbn"/>
</f:facet>
<h:link value="#{item.isbn}" outcome="#{bookController.getLibraryBook(item.isbn)}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Title"/>
</f:facet>
<h:outputText value="#{item.title}"/>
</h:column>
<h:column>
<h:commandButton value='Update' class="btn btn-warning" action="#{bookController.EditBook(item)}"></h:commandButton>
<h:commandButton value='Delete' class="btn btn-danger" action="#{bookController.deleteBook(item.isbn)}"></h:commandButton>
</h:column>
</h:dataTable>
</h:form>
</f:view>
因为 <h:link outcome>
在页面呈现时计算,而不是在您单击 link 时计算。您在 outcome
中引用的方法将会话作用域 bean 属性 设置为当前项,然后 returns 一个字符串 bookOverview
。因此,实际上,在您单击之前,每个 link 都有一个 outcome="bookOverview"
。与此同时,bean 只记得最后一项。
<h:commandLink action>
有效,因为它是在您单击 link 后计算的。
这种差异是因为 <h:link>
用于不需要状态 <h:form>
的幂等 (GET) 请求,而 <h:commandLink>
用于非幂等 (POST) 需要有状态 <h:form>
.
的请求
另请参阅:
- When should I use h:outputLink instead of h:commandLink?
- How to navigate in JSF? How to make URL reflect current page (and not previous one)
也就是说,您要解决的真正问题已在此处得到解答:Creating master-detail pages for entities, how to link them and which bean scope to choose。它展示了如何正确使用 <h:link>
以及您实际应该使用的 bean 范围。
当我想查看我的书的详细信息页面时,我会拿到我的书并将其重定向到我的概览页面。现在,当我使用 <h:link>
时,他总是给出我的数据表的最后一项。当我使用 <h:commandLink>
时,一切正常。现在我的问题是,为什么 <h:link outcome="...">
不工作,而 <h:commandLink>
中的 'same' 代码可以工作?
托管 Bean
@Named(value = "bookController")
@SessionScoped
public class BookController implements Serializable {
@EJB private BookRepository dao;
private LibraryBook book = new LibraryBook();
...
public String getLibraryBook(String isbn)
{
this.book = this.dao.getBook(isbn);
return "bookOverview";
}
...
}
Book.xhtml
<f:view>
<h:form>
<h:dataTable value="#{bookController.books}" var="item" class="table">
<h:column>
<f:facet name="header">
<h:outputText value="Isbn"/>
</f:facet>
<h:link value="#{item.isbn}" outcome="#{bookController.getLibraryBook(item.isbn)}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Title"/>
</f:facet>
<h:outputText value="#{item.title}"/>
</h:column>
<h:column>
<h:commandButton value='Update' class="btn btn-warning" action="#{bookController.EditBook(item)}"></h:commandButton>
<h:commandButton value='Delete' class="btn btn-danger" action="#{bookController.deleteBook(item.isbn)}"></h:commandButton>
</h:column>
</h:dataTable>
</h:form>
</f:view>
因为 <h:link outcome>
在页面呈现时计算,而不是在您单击 link 时计算。您在 outcome
中引用的方法将会话作用域 bean 属性 设置为当前项,然后 returns 一个字符串 bookOverview
。因此,实际上,在您单击之前,每个 link 都有一个 outcome="bookOverview"
。与此同时,bean 只记得最后一项。
<h:commandLink action>
有效,因为它是在您单击 link 后计算的。
这种差异是因为 <h:link>
用于不需要状态 <h:form>
的幂等 (GET) 请求,而 <h:commandLink>
用于非幂等 (POST) 需要有状态 <h:form>
.
另请参阅:
- When should I use h:outputLink instead of h:commandLink?
- How to navigate in JSF? How to make URL reflect current page (and not previous one)
也就是说,您要解决的真正问题已在此处得到解答:Creating master-detail pages for entities, how to link them and which bean scope to choose。它展示了如何正确使用 <h:link>
以及您实际应该使用的 bean 范围。