通过Seam,RichFaces& PopupPanel

时间:2011-06-29 15:43:04

标签: java jsf-2 seam cdi seam3

我正在尝试使用Seam 3,RichFaces 4进行一些小应用程序,并通过传递一些参数来解决一些麻烦。我已经尝试了很多不同的东西但是我在最后的障碍中不断下降。我通过请求参数传递customerId。但是当我在popupPanel上点击RichFaces commandButton时,我不再使用该customerId。

我正在设置一个应用程序来管理一些数据。基本上,您从一个屏幕中选择一个客户,这将带您到另一个包含“存储库”的屏幕,然后您可以在其中创建,编辑等。您可以通过URL访问第二个存储库页面:

http://localhost:8080/media-manager/repositories.xhtml?customer=12

然后我有一个bean选择这个值:

@Named
@RequestScoped
public class RepositoryBean extends AbstractViewBean<Repository> {
    // Various properties etc. here

    private Long customerId;

    public void init() {
        log.info("Customer ID is "+ customerId);
    }
}

然后我通过存储库页面上的元数据设置客户ID并调用init:

<f:metadata>
  <f:viewParam name="customer" value="#{repositoryBean.customerId}"/>
  <f:event type="preRenderView" listener="#{repositoryBean.init}" />
</f:metadata>

这一开始效果很好。我可以使用提供的ID显示客户需要的信息。但是当我尝试创建我的popupPanel时有点不对劲。这是代码的简化版本:

<rich:popupPanel id="repositoryModalPanel" modal="true" resizeable="true">
  <f:facet name="header">Title</f:facet>
  <f:facet name="controls">
    <h:outputLink value="#" onclick="#{rich:component('repositoryModalPanel')}.hide(); return false;">X</h:outputLink>
  </f:facet>
  <h:form id="modalForm" class="modalForm">
    <fieldset>
    <ul class="layout form">
      <li>
        <label for="name" class="required">Name:</label>
        <h:inputText id="name" value="#{repositoryBean.instance.name}" required="true">
          <!-- rich:validator event="blur" / -->
        </h:inputText>
        <rich:message for="name" errorClass="error errormessage" />
      </li>
      <li class="last">
        <a4j:commandButton id="create" value="Create" action="#{repositoryBean.saveRepository}" rendered="#{empty repositoryBean.instance.id}"/>
        <a4j:commandButton id="save" value="Save" action="#{repositoryBean.saveRepository}" rendered="#{not empty repositoryBean.instance.id}"/>
        <a4j:commandButton id="cancel" value="Cancel" action="#{repositoryBean.clearInstance}" immediate="true" />
      </li>
    </ul>
  </fieldset>
</h:form>

基本上,每当我点击save commandButton时,都会调用init方法,但永远不会填充customerId成员。有没有人知道为什么?

我已经读过viewParam仅用于GET请求,所以这可能是问题所在?但如果是这样的话 - 另一种解决方案是什么?我见过很多建议(例如使用@ManagedProperty)似乎不适用于Seam 3.

1 个答案:

答案 0 :(得分:1)

RepositoryBean是RequestScoped,因此将在每个请求上新创建,特别是如果您点击了保存按钮。

直接的解决方案是将RepositoryBean提升为ConversationScoped,并在进入该页面时使其长时间运行。

@Named
@ConversationScoped
public class RepositoryBean extends AbstractViewBean<Repository> {
    // Various properties etc. here

    @In
    Conversation conversation

    private Long customerId;

    public void init() {
        log.info("Customer ID is "+ customerId);
        conversation.begin();
    }
}

最简单的方法是转储preRenderView并改为使用seam 3 view-action。

<f:metadata>
  <f:viewParam name="customer" value="#{repositoryBean.customerId}"/>
  <s:viewAction action="#{repositoryBean.init}" if="#{conversation.transient}"/>
</f:metadata>