如何通过导航菜单刷新动态内容?(JSF水疗中心)

如何通过导航菜单刷新动态内容?(JSF水疗中心),jsf,single-page-application,facelets,uiinclude,ajax-update,Jsf,Single Page Application,Facelets,Uiinclude,Ajax Update,我只是在学习JSF2,多亏了这个网站,我在这么短的时间里学到了很多东西 我的问题是如何在我的所有JSF2页面上实现一个通用的布局,并且每当我从另一个面板单击链接/菜单时,只刷新页面的内容部分而不是整个页面。我使用的是Facelets方法,它实现了我想要的功能,除了每次单击面板中的链接(例如,左面板中的菜单项)时,整个页面都会刷新。我正在寻找的是一种只刷新页面内容部分的方法。为了说明这一点,下面是我的目标页面布局 没有发布我的代码,因为我不确定Facelets是否可以做到这一点。除了Facele

我只是在学习JSF2,多亏了这个网站,我在这么短的时间里学到了很多东西

我的问题是如何在我的所有JSF2页面上实现一个通用的布局,并且每当我从另一个面板单击链接/菜单时,只刷新页面的内容部分而不是整个页面。我使用的是Facelets方法,它实现了我想要的功能,除了每次单击面板中的链接(例如,左面板中的菜单项)时,整个页面都会刷新。我正在寻找的是一种只刷新页面内容部分的方法。为了说明这一点,下面是我的目标页面布局


没有发布我的代码,因为我不确定Facelets是否可以做到这一点。除了Facelets之外,还有其他更适合我的需求的方法吗?

如果您只想刷新页面的一部分,那么只有两种方法(对于一般的web,而不仅仅是JSF)。您必须使用frames或Ajax。jsf2本机支持ajax,请查看f:ajax标记,只更新1个组件而不重新加载整个页面。

Netbeans提供了一个向导,使用JSF以最小的工作量创建建议的布局。因此,最好的开始方法是查看并查看生成的源代码。

一个简单的方法是以下视图:


标题
使用此bean:

@ManagedBean
@ViewScoped
public class Bean implements Serializable {

     private String page;

     @PostConstruct
     public void init() {
         page = "include1"; //  Default include.
     }

     // +getter+setter.
 }
在本例中,实际的include模板是
include1.xhtml
include2.xhtml
include3.xhtml
/WEB-INF/includes
文件夹中(文件夹和位置完全由您选择;文件只是放在
/WEB-INF
中,以便通过猜测浏览器地址栏中的URL进行编辑)

这种方法适用于所有MyFaces版本,但至少需要Mojarra 2.3.0。如果您使用的Mojarra版本早于2.3.0,那么当
页面依次包含
时,这一切都会失败。任何回发都将失败,因为它完全缺少视图状态。您可以通过升级到最低限度的Mojarra 2.3.0或使用此答案中的脚本来解决此问题,或者如果您已经在使用JSF实用程序库,请使用其。或者,如果您已经在使用PrimeFaces并专门使用ajax,那么它已经被透明地考虑进去了

此外,请确保您使用的Mojarra 2.1.18版本最少,因为旧版本将无法保持视图范围bean的活动状态,从而导致在回发期间使用错误的include。如果无法升级,则需要退回到以下(相对笨拙的)方法,即有条件地渲染视图,而不是有条件地构建视图:

。。。
缺点是视图会变得相对较大,并且所有相关联的托管bean可能会被不必要地初始化,即使它们不会按照呈现的条件使用

至于元素的定位,这只是应用正确的CSS的问题。这超出了JSF的范围:)至少,
呈现了一个
,所以这应该足够好了


最后但并非最不重要的一点是,这种SPA(单页应用程序)方法对SEO不友好。所有页面都不可由搜索机器人索引,也不可由最终用户进行书签,您可能需要在客户端处理HTML5历史记录,并提供服务器端回退。此外,对于带有表单的页面,相同的视图范围的bean实例将在所有页面上重用,从而在您导航回以前访问过的页面时产生不直观的作用域行为。我建议使用模板化方法,如本答案第二部分所述:另请参见。

ajax加载/刷新部分如何?Netbeans是否也生成该部分?我不这么认为。是的,你是对的。Netbeans不会生成那个部分。但是它有一个很好的向导来定义布局。ajax部分显然必须手动完成。有很多方法可以做到这一点,从使用“rendered”属性到使用ui:include src=“…”。如果一个页面上有多个表单,并且需要保持“同步”状态,则可以在myfaces上使用此hack:window.myfaces=window.myfaces | |{};myfaces.config=myfaces.config | |{};myfaces.config.no_portlet_env=true;正如我所经历的,对于包含表单的include内容来说,这不太好。是的……可能还需要在表单中包装整个部分,而不是在ajaxified部分中包含表单。我指的是使用
语法。由于某些原因,在回发的还原视图期间,src的解析方式与在呈现响应期间的解析方式不同,这反过来导致找不到表单,因此未处理任何内容。但这也可能只是莫哈拉病毒。我不确定。然而,有趣的是,我尝试了MyFaces 2.1.1,但它在渲染响应期间并未显示所需的动态包含。要使工作ui:include src=“…”与facelets 1.1.x一样,您必须将web配置参数org.apache.MyFaces.REFRESH_TRANSIENT_BUILD_ON_PSS设置为true。详细信息请参阅。正是我要找的!!!加上实现简洁易懂。幸运的是,我计划使用的应用程序更多的是一个企业局域网应用程序,而且我的用户不要求它对SEO友好、可搜索(如果可搜索是一个词):)和可书签,这就是为什么它适合我的要求。非常感谢。嗨,谢谢你的精彩回答。我在这个模板中有一个提交表单,比如include1,我想通过命令按钮转到include2,但需要单击两次。有没有办法纠正这个问题?@BulusC:我如何使用fixviewstate.js处理primeface4(@Sima:I