从视图初始化托管Bean

时间:2011-02-09 16:39:49

标签: jsf-2 primefaces

我很难处理应用程序应该在我的应用程序中使用的内容。

我使用的是Primefaces,用于我的初始视图布局。在布局之外,我有许多不同的托管bean使用的对话框。

在我的布局中,我有一个页眉,页脚左侧的导航,然后是中心的当前视图。所以我的观点如下:

<h:body id=body">
   <p:layoutUnit id=head" position="top">
         <ui:insert name="header">
   </p:layoutUnit>
   <p:layoutUnit id=head" position="bottom">
         <ui:insert name="footer">
   </p:layoutUnit>
   <p:layoutUnit id=head" position="left">
         <ui:insert name="menu">
   </p:layoutUnit>
   <p:layoutUnit id=head" position="right">
         <ui:insert name="main">
   </p:layoutUnit>

   <p:dialog widgetVar="addAddressDialog" header="Add New Address">
       <h:form id="insertAddress">
            <h:inputText id="insert_address" label="Address" />
       </h:form>
   </p:dialog>

   <p:dialog widgetVar="updateAddressDialog" header="Add New Address">
       <h:form id="updateAddress">
            <h:inputText id="update_address" value=#{addressBean.selectedAddress.address" />
       </h:form>
   </p:dialog>

我遇到的问题是当我的应用程序第一次加载时,由于正在加载视图,因此调用了addressBean的@PostConstruct。在@PostConstruct中,我初始化与名为contactId的特定id相关联的地址列表。此时虽然contactId尚未实例化。一旦用户与“主”视图交互,就会发生这种情况。

我对addressBean的作用域目前是@ViewScope,它可以找到但只是第一次设置了contactId。之后,即使contactId发生更改,它也会继续保留已填充的信息,因为@PostConstruct永远不会再次被调用,并且视图似乎永远不会超出范围。

我试过@RequestScope,这实际上非常好。但是在“主”视图中的数据表中显示地址时遇到了问题。我的数据表底部有一个调用insertAddressDialog.show()的按钮。它第一次打开,我可以插入数据,但是1.数据表的视图从不显示我插入的新记录,因为我猜视图已经丢失了。 2.数据表上的按钮不再处于活动状态或活动状态,因此在用户第一次插入记录后,对话框不会打开。

这似乎应该是一件容易的事,但我的应用程序有许多嵌套视图导致问题。任何关于如何处理这样的事情的见解都会有所帮助。

1 个答案:

答案 0 :(得分:0)

这听起来不像PrimeFaces问题。

只要您不离开与其关联的页面(视图),ViewScoped bean就会保留在范围内。每次与它交互时,RequestScoped bean都会重新实例化。如果你试图在一次交互中将变量存储到RequestScoped bean中,然后在第二次交互时用这些变量更新数据库,第二次交互将重新实例化bean,你的变量将会消失(好吧,变量仍然存在 - 它的价值消失了。)

使用@PostConstruct初始化地址是否有令人信服的理由?听起来你有一个主页面,用户开始与程序交互,从用户输入的主页面(或程序以其他方式检索)用户的contactId。此contactId变量用于填充数据表,显示与该用户的contactId关联的所有地址。这听起来像是你的bean逻辑错误。

您需要先获取contactId,然后使用它来填充数据表。我不知道你的程序/用户如何与bean交互以提供contactId。如果从用户输入contactId,则不要初始化@PostConstruct中的地址列表,因为它将始终在输入contactId之前初始化。如果程序从一个类型为user的变量(它知道因为用户已登录并且程序从数据库创建/检索用户的contactId)而自动获取contactId,则应该能够包含该代码@PostConstruct - 在初始化数据表之前。

或者,不要使用@PostConstruct,只需在您的网页(视图)引用任何变量 之前的网页 中包含方法调用。您只需将方法调用放在页面上即可:

          #{} myBean.myMethod                  这里的其他代码......           

应该在进行方法调用之前调用和构造bean,并且用户的contactId应该可用于bean的数据操作。 (我在最后一点做了一个假设,因为我们看不到你的bean逻辑。)