本文共 1350 字,大约阅读时间需要 4 分钟。
引入:
项目组问我,如果一个Portlet有多个模式(比如我们以前开发的某portlet同时有view模式和config模式),而我们前端用的extjs mvc的架构,并且主文件是main.js,这个main.js是用以下的<footer-portlet-javascript>定义在liferay-portlet.xml中,如下:
那么可能不可能让view.jsp(view模式的页面文件)和config.jsp(config模式的页面文件)分别加载2次main.js而不是共享同一个 main.js呢?
分析:
我仔细研究了一下,发现这是不可能做到的,以下是理由和我的想法。
首先,对于我们在iferay-portlet.xml中以这种方式定义的加载js文件,最终会被Liferay框架的PortletLocalServiceImpl的第1549-1551 行读取并且处理。
换句话说,我们这些所有的<footer-portlet-javascript>的配置,都会被框架读取并且加入到footerPortletJavaScriptList列表中。
那么这些列表中的js文件如何被使用呢?阅读Liferay源码,我们找到了,它原来在bottom_portlet_resources_js.jspf文件中,见第33行:
可以发现,它会读取刚才的footerPortletJavaScriptList,然后吧所有的资源文件路径解析为绝对路径,然后分别用<script src>的方式引入。
而bottom_portlet_resource_js.jspf中会被bottom.jsp引入:
而bottom.jsp会在init.vm中364行被存入一个vm变量叫$bottom_include中:
而$bottom_include会在我们的theme中的portal_normal.vm中65行被引入:
总结:
因为我们一定会使用theme,无论使用默认的还是我们自定义的比如本例的platform_theme,不管哪一个,其中必定会包含portal_normal.vm,它会包含bottom.jsp,进而包含bottom_portlet_resources_js.jspf。
而这个jspf页帧则包含了所有以footer-portlet-javascript形式给出的js资源文件。因为我们这个portal_normal.vm是项目框架级别的,所以只会解析一次,并且所有的页面都在这个框架中。
这就是为什么js资源只会加载一次的原因,而且无论是iframe,或者额外弹出页面,都在这个框架中,所以都会读到这些js文件,并且是相同的js文件。
从这个意义上说,我们让其分别引入js文件,并且都是main.js文件,并且都以footer-portlet-javascript给出的是不可行的,除非,这个js文件不定义在liferay-portlet.xml的<footer-portlet-javascript>元素中。