我已经使用了一段时间的JSF,但有些东西总让我困惑。希望有人可以提供帮助。
简单的例子,有一个显示“Person”表的页面,当你点击“Person”名字时,它会带你到一个页面来查看“Person”的详细信息。
通常,我会像这样实现personSearch.jsf页面:
<h:dataTable value="#{personHandler.persons}" var="person">
<h:column>
<h:commandLink action="#{personHandler.show( person.id )}" >
<h:outputText value="#{person.name}" />
</h:commandLink>
</h:column>
</h:dataTable>
我实现了一个personView.jsf页面:
<h:panelGrid columns="2">
<h:outputText value="Person ID:" />
<h:outputText value="#{personHandler.selectedPerson.id}" />
<h:outputText value="Person Name:" />
<h:outputText value="#{personHandler.selectedPerson.name}" />
</h:panelGrid>
PersonHandler.show(Integer personId)设置personHandler.selectedPerson,然后重定向到personView页面。
当PersonHandler是会话bean时,这一切都正常。但我更喜欢它是一个请求范围的bean,因为用户可能打开了几个窗口,我不希望每个会话只有一个选定的人。
所以我的问题是,做这个JSF的“正确”方法是什么?我曾经能够使用a4j得到我想要的东西:keepAlive on the personHandler,但这总觉得像一个kludge。同样,这是我从未理解的JSF。
非常感谢任何帮助! 抢劫
答案 0 :(得分:2)
如果视图应该是可收藏的,请将人员ID作为GET请求参数而不是POST请求“参数”传递。
<h:outputLink value="viewperson.xhtml">
<f:param name="id" value="#{person.id}" />
</h:outputLink>
这样你可以使用两个@RequestScoped
bean,一个用于列表,一个用于视图。您可以按如下方式预加载所选人员:
@ManagedProperty(value="#{param.id}")
private Long id;
@PostConstruct
public void init() {
selectedPerson = personDAO.find(id);
}
如果它不应该是可收藏的,那么只需创建一个有条件地呈现视图状态的视图。
<ui:fragment rendered="#{!personHandler.viewMode}">
<h:form>
<h:dataTable value="#{personHandler.persons}" var="person">
<h:column>
<h:commandLink value="#{person.name}" action="#{personHandler.show(person)}" />
</h:column>
</h:dataTable>
</h:form>
</ui:fragment>
<ui:fragment rendered="#{personHandler.viewMode}">
<h:form>
...
<h:commandLink value="Go back" action="#{personHandler.back}" />
</h:form>
</ui:fragment>
(如果需要,您可以将两个framgents的内容拆分为<ui:include>
所包含的另一个Facelet文件)
这样,您可以使用单个@ViewScoped
bean,其操作方法返回void
或null
。
public void show(Person selectedPerson) {
this.selectedPerson = selectedPerson;
}
public void back() {
selectedPerson = null;
}
public boolean isViewMode() {
return selectedPerson != null;
}
您甚至可以将整个视图包装在某些
中<h:panelGroup id="container">
并在两个命令链接中嵌套以下内容,让Ajax魔术完成工作
<f:ajax execute="@form" render=":container" />