我正在使用facelet模板,我认为我遇到了ui:define和JSF生命周期的问题。我的template.xhtml在标题中包含一个固定的菜单,简化它有这样的链接:
<h:commandLink value="Click Me">
<f:ajax update="#{myBean.listener}" render="contentpanel"/>
</h:commandLink>
template.xhtml还包含一个ui:insert语句:
<ui:insert name="content">
<h:outputLabel value="content placeholder"/>
</ui:insert>
现在我有一个content.xhtml,它看起来像:
<ui:composition template="template.xhtml">
<ui:define name="content">
<h:panelGroup id="contentpanel"/>
</ui:define>
</ui:composition>
引入的内容非常多。当我点击命令链接'点击我'时,我正在打电话给我的听众。此侦听器在backingbean中设置引用,以根据我单击的链接动态加载内容。
第一次按下commandlink时,不会执行此渲染。好吧,它基本上看起来像它首先重新渲染然后调用监听器而不是相反。所以当我第一次点击时,似乎没有任何事情发生。当我第二次点击时,我会看到为第一次点击设置的内容。当我第三次点击时,我会看到第二次点击的内容。
我认为这是因为ui:define视图已经在JSF生命周期的“恢复视图”阶段重新构建。关于如何克服这个问题的任何想法?
更新
似乎我的假设是错误的。其原因似乎有所不同。 #{myBean.listener}
有@SessionScoped @ManagedProperty
,点击CommandLink后会更新#{myBean.data}
。 contentpanel实际上通过@RequestScoped
#{myBean.data}
加载数据。此getData()
未正确重新加载数据。我通过将@SessionScoped
方法直接传递给ui:define / ui:insert
bean来解决它。
可能有点混乱。但我的结论是:确实可以部分渲染通过facelet模板加载的组件({{1}})
答案 0 :(得分:1)
似乎我的假设是错误的。其原因似乎有所不同。 #{myBean.listener}有一个@SessionScoped @ManagedProperty,在单击CommandLink后会更新。 contentpanel实际上通过@ {myBean.data}加载数据,这是@RequestScoped。此#{myBean.data}未正确重新加载数据。我通过将getData()方法直接传递给@SessionScoped bean来解决它。
可能有点混乱。但我的结论是:它可以部分渲染通过facelet模板加载的组件(ui:define / ui:insert)