extjs中动态加载机制研究

简介:

昨天我们team对于extjs的动态加载机制做了些深入研究,这里先share下controller加载的结果。


以service registry portlet为例:

比如,在 liferay-portlet.xml中定义了:

所以我们的js的入口点是app.js,这其中创建了Ext.application并且声明了动态加载controller:

1
2
3
4
5
6
7
Ext.application({
    name:  'serviceRegistry' ,
    appFolder:  '/serviceregistryportlet/js/app' ,
    controllers:[ 'mainPanel' ],
    launch: function (){
...
)


我们这里具体看extjs是如何实现动态加载controller的。


首先我们可以看到,当它在加载controller时候,所有这里声明的controller的都会以类全名的形式传递给classNames属性


Ext.Loader的config选项paths会收到2个属性,一个是默认的Ext的path,它的默认值定义如下:

1
2
3
4
5
6
7
8
9
10
11
12
config: {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
            enabled:  false ,
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
            disableCaching:  true ,
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
            disableCachingParam:  '_dc' ,
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
            paths: {
                'Ext' '.'
            }
        },


另外一个就是从Ext.application中获取的属性,它的key 为Ext.application中定义的name(在这里是serviceRegistry),

value为Ext.application中定义的appFolder(在这里是/serviceregistryportlet/js/app)

如下图所示:



然后在第5314行,就通过另外一个方法getPrefix()来根据controller的类名来获取它的前缀,并且这个前缀会最终参与到运算。我们这里省去这段逻辑,反正最终,这个"serviceRegistry.controller.mainPanel'的前缀是"serviceRegistry",如上图的调试结果。


注:以上的所有结论和我昨天猜想的完全一致,昨天并没有调试结论,看来我计算机感觉不错,小得意一下~


既然上面paths给出了2个候选的路径名(一个是Ext级别的,一个是项目serviceRegistry级别的),这2个路径名都有可能作为最终加载资源文件的备选路径,那么选取哪一个路径作为最终加载路径呢?就要看下面的分析了。


刚才因为已经得到了prefix=serviceRegistry,所以我们通过第5321行: path=paths[prefix] 来最终得到了真正要加载的路径名,也就是"/serviceregistryportlet/js/app"

紧接着,class的名字也确定下来了,就是类的全名(classFullName)去除掉前缀(prefix),所以也就是"serviceRegistry.controller.mainPanel",去除掉"serviceRegistry",剩下来"controller.mainPanel":

以上2个信息都可以从调试的结果看出来;


所以最后工作就很清楚了,它会吧所有的路径名中的"."替换成"/" ,然后最后结尾加上".js"文件扩展名,所以最终就成了js controller文件的资源路径:

这个路径是正确的而且是我们预期的。。



所以从以上调试,我们可以总结出以下结论:

(1)对于controller而言,它的加载路径总是有2个备选路径,一个是Ext框架级别的备选路径,它的默认值是当前目录".",另外一个是项目级别的路径,并且项目级别的路径的优先级高于框架级别。只有项目级别路径加载不到js资源文件才会从框架级别的路径中加载js文件。

(2)对于controller而言,要计算出项目级别的路径,不得不获取很多相关信息,比如说前缀,controller的类名,路径名。其中Ext.application的项目名(name)的作用是提供了项目级别路径的key,Ext.application的(appFolder)提供了项目级别路径的value, 前缀是通过类的全名解析出来的。

(3)一般类的全名的前缀部分最好和Ext.application的项目名(name)一致,其原因是,资源文件最终路径path是通过path=paths[prefix]计算出来的。如果不一致的话,要走else 分支。

(4)所有的资源文件最终路径都是用.分割的路径最终替换成的/分割的路径并且尾部追加扩展名来形成的,项目中任何地方不会涉及裸露的路径字符串。

(5)在任何情况下controller总能被正确的加载,只要appFolder设置正确。比如说我们把Ext.application的name设置成"hello",吧appFolder设置为"/xxx/js/app",但是,我们某个controller文件,我们的前缀并不设置为"hello" ,而是设置成其他的,比如fxxk,所以controller的类全名是"fxxk.controller.ABCController",在这种情况下。prefix因为是从"fxxk.controller.ABCController"字符串中分析来的,所以它的值是“fxxk",而appName因为是"hello",所以paths中有2个值,一个是key="Ext" ,value=".",另外一个是 key="hello",value="/xxx/js/app",所以执行path=paths[prefix]值时,它没办法获取任何值,所以保留原来的默认值"" 空字符串。但是,className是用"fxxk.controller.ABCController"去除prefix "fxxk",所以,className是正确的,还是"controller.ABCController",所以在最后5329行拼接path时候:path.replace(slashDotSlashre,'/')依然返回"", 而className是正确的,所以className.replace(dotRe,"/"),会返回/controller/ABCController.最后拼接上.js扩展名。所以这个文件依然能正确加载。





本文转自 charles_wang888 51CTO博客,原文链接:http://blog.51cto.com/supercharles888/1244064,如需转载请自行联系原作者
目录
相关文章
|
4月前
|
JavaScript 前端开发
JavaScript引入全攻略:提升网页加载速度的秘诀!
JavaScript引入全攻略:提升网页加载速度的秘诀!
|
JavaScript
js基础笔记学习250事件委派1
js基础笔记学习250事件委派1
139 0
js基础笔记学习250事件委派1
|
JavaScript
js基础笔记学习252事件委派3
js基础笔记学习252事件委派3
69 0
js基础笔记学习252事件委派3
|
JavaScript
js基础笔记学习251事件委派2
js基础笔记学习251事件委派2
64 0
js基础笔记学习251事件委派2
|
自然语言处理
tinymce 如何实现动态国际化
tinymce 是一个非常强大的富文本编辑器,tinymce是支持开启通过配置 language 来决定 tinymce 的语言版本例如下面配置 日文 英文 中文 且在同一个页面
397 1
tinymce 如何实现动态国际化
|
前端开发 JavaScript API
初入项目,JS可能遇到的问题优化以及处理方法
在刚进入项目时候,很可能遇到一些问题,我这里分成了三个模块,第一个模块是ES6的一些方法的妙用,整理了一些可能会被人忽略的函数以及一些参数的使用;第二个模块是有关if else的一些技巧,说来也是刚到阿里园区收到一位老哥影响,做了一些学习,对一些使用做了下整理;最后一个模块是有关react hook的入门,对于hook来说,最常用的一些地方就是组件传值以及组件传方法,在这里我对这部分所涉及的各种情况做了一些整理,希望对大家有所帮助,当然我也是能力有限,一些笔误或者使用上不够规范的欢迎留言或私我讨论。
|
JavaScript 前端开发
前端优化系列 - JS混淆引入性能天坑
现在前端渲染变得越来越普遍。前端渲染主要依赖JS去完成核心逻辑,JS正变得越来越重要。本文详细谈谈JS混淆对性能的影响。
4213 0
|
存储 Java Android开发
Android插件化开发之动态加载技术学习
Android插件化开发之动态加载技术学习 为什么要插件化开发和动态加载呢?我认为原因有三点: 可以实现解耦 可以解除单个dex函数不能超过65535的限制 可以给apk瘦身,比如说360安全卫士,整个安装包才13.
2118 0