JSF:这样做的“正确”方法是什么?

时间:2011-04-04 22:59:30

标签: jsf

我已经使用了一段时间的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>

PersonH​​andler.show(Integer personId)设置personH​​andler.selectedPerson,然后重定向到personView页面。

当PersonH​​andler是会话bean时,这一切都正常。但我更喜欢它是一个请求范围的bean,因为用户可能打开了几个窗口,我不希望每个会话只有一个选定的人。

所以我的问题是,做这个JSF的“正确”方法是什么?我曾经能够使用a4j得到我想要的东西:keepAlive on the personH​​andler,但这总觉得像一个kludge。同样,这是我从未理解的JSF。

非常感谢任何帮助! 抢劫

1 个答案:

答案 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,其操作方法返回voidnull

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" />