Visual Studio(下面简称VS) 2008和2010都有从JS库文件获取智能提示的功能,不过直接使用ExtJS的库文件的话,虽然也有提示,但是不全,应该说是大部分没有,主要原因是VS脚本提示功能是根据原生JavaScript对象的结构读取,而ExtJS的对象定义与原生JavaScript对象完全不同,因而很难取得其属性和方法。因而,要完整支持ExtJS的智能提示,就必须将ExtJS对象的属性和方法提炼出来,然后组织成一个VS能读懂的JavaScript对象结构,这样就能实现智能提示了。
要将ExtJS对象的属性和方法提取出来不难,从图1中DOM树中的Ext对象结构,可以看到,只要遍历一次Ext对象就可以取得所有对象的属性和方法。不过,实际上,不是那么容易,原因是在ExtJS的对象中,有些是实例,有些是函数形式的对象,对于实例,其属性和方法直接在对象内,而对于函数形式的对象,其属性和方法却是在原型内,因而要区别对待。
还有一个重要问题,就是命名空间的问题,如Ext.menu.Item、Ext.data.Store或Ext.layout.container.VBox这些3或4级的类名。采用递归遍历,存在的问题是,判断该对象是JavaScript对象还是ExtJS方式定义的对象存在难度,因而,最好的方式是使用附录中的类名列表,通过它去遍历对象。这样就简单很多了。在列表中,如果对象是实例,使用Ext的isObject方法,其值会是true,否则,该对象就是函数式对象,需要实例化才能使用,因而属性和方法在原型内,不过这里要注意可能存在静态方法,因而为了避免遗漏,还得遍历对象本身的属性和方法。
Ext对象本身需要另外加进去,主要原因是它不同于其他对象那样可直接通过对象本身或原型提取属性和方法,需要把在类列表中的类排除出去,这个可通过对象或函数是否存在“$className”属性解决。
还有对象的别名问题,这个直接从ClassManager对象的maps对象中的alternateToName属性中取得,将别名直接指向对象VS就认识了。
最后的问题是如何将对象输出到页面,这个使用encode方法就可以自动转了。
命名空间的问题,可通过ns方法解决,它会自动根据类名创建对象,只要别和Ext对象发生冲突就行了。
目标明确后,现在可以开始工作,创建一个名称为VS-Ext.html的文件,然后加入以下代码:- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
- <html>
- <head>
- <title>第1章 在Visual Studio中实现智能提示</title>
- <link rel="stylesheet" type="text/css" href="../Ext4/resources/css/ext-all.css"/>
- <script type="text/javascript" src="../Ext4/bootstrap.js"></script>
- <script type="text/javascript" src="class.js"></script>
- </head>
- <body>
- <script type="text/javascript">
- Ext.onReady(function(){
- //建立命名管道
- Ext.ns("VS.Ext");
- var processPrototype=function(s,d){
- //处理静态方法
- for(var c in s){
- if(s.hasOwnProperty(c)){
- d[c]="";
- }
- }
- //处理原型
- for(var c in s.prototype){
- d[c]="";
- }
- }
- //处理实例
- var processInst=function(s,d){
- var i=0;
- for(var c in s){
- d[c]="";
- }
- }
- //处理Ext对象
- for(var c in Ext){
- if(Ext.hasOwnProperty(c)){
- var p=Ext[c];
- if(Ext.isObject(p)){
- if(!p["$className"]){
- if( ["buildSettings","versions","lastRegisteredVersion"].indexOf(c)>=0 ){
- VS.Ext[c]=p;
- }
- }
- }else if(Ext.isFunction(p)){
- if(!p["$className"]){
- VS.Ext[c]="";
- }
- }else{
- VS.Ext[c]="";
- }
- }
- }
- //枚举对象
- Ext.Array.each(classList,function(classname){
- Ext.ns("VS."+classname);
- var d=classname.split("."),
- sobj=Ext[d[1]],
- dobj=VS.Ext[d[1]];
- if(d.length >= 3){
- sobj=sobj[d[2]],
- dobj=dobj[d[2]];
- }
- if(d.length == 4){
- sobj=sobj[d[3]];
- dobj=dobj[d[3]];
- }
- if(sobj && dobj){
- if(Ext.isObject(sobj)){
- processInst(sobj,dobj);
- }else{
- if(sobj.prototype){
- processPrototype(sobj,dobj);
- }
- }
- }
- })
- var html="Ext="+Ext.encode(VS.Ext)+"<br/>";
- //处理别名
- for(var c in Ext.ClassManager.maps.alternateToName){
- html+=c+"="+Ext.ClassManager.maps.alternateToName[c]+"</br>";
- }
- Ext.getBody().dom.innerHTML=html;
- })
- </script>
- </body>
- </html>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>第1章 在Visual Studio中实现智能提示</title>
<link rel="stylesheet" type="text/css" href="../Ext4/resources/css/ext-all.css"/>
<script type="text/javascript" src="../Ext4/bootstrap.js"></script>
<script type="text/javascript" src="class.js"></script>
</head>
<body>
<script type="text/javascript">
Ext.onReady(function(){
//建立命名管道
Ext.ns("VS.Ext");
var processPrototype=function(s,d){
//处理静态方法
for(var c in s){
if(s.hasOwnProperty(c)){
d[c]="";
}
}
//处理原型
for(var c in s.prototype){
d[c]="";
}
}
//处理实例
var processInst=function(s,d){
var i=0;
for(var c in s){
d[c]="";
}
}
//处理Ext对象
for(var c in Ext){
if(Ext.hasOwnProperty(c)){
var p=Ext[c];
if(Ext.isObject(p)){
if(!p["$className"]){
if( ["buildSettings","versions","lastRegisteredVersion"].indexOf(c)>=0 ){
VS.Ext[c]=p;
}
}
}else if(Ext.isFunction(p)){
if(!p["$className"]){
VS.Ext[c]="";
}
}else{
VS.Ext[c]="";
}
}
}
//枚举对象
Ext.Array.each(classList,function(classname){
Ext.ns("VS."+classname);
var d=classname.split("."),
sobj=Ext[d[1]],
dobj=VS.Ext[d[1]];
if(d.length >= 3){
sobj=sobj[d[2]],
dobj=dobj[d[2]];
}
if(d.length == 4){
sobj=sobj[d[3]];
dobj=dobj[d[3]];
}
if(sobj && dobj){
if(Ext.isObject(sobj)){
processInst(sobj,dobj);
}else{
if(sobj.prototype){
processPrototype(sobj,dobj);
}
}
}
})
var html="Ext="+Ext.encode(VS.Ext)+"<br/>";
//处理别名
for(var c in Ext.ClassManager.maps.alternateToName){
html+=c+"="+Ext.ClassManager.maps.alternateToName[c]+"</br>";
}
Ext.getBody().dom.innerHTML=html;
})
</script>
</body>
</html>
代码中,先创建新的命名空间“VS.Ext”,在其内放置对象的属性和方法。
函数processPrototype用于处理非实例的对象,第一个循环主要是遍历静态属性和方法。第二个循环用于遍历原型的属性和方法。
函数processInst用于遍历实例的属性和方法,在这里不能加hasOwnProperty方法检测属性或方法是否其拥有的,不然会找不到属性和方法,除非是在实例创建后加的属性和方法。
接着处理Ext对象,如果属性指向的是对象,还要排除grid、form等对象干扰,因而这个要自己查看一下Ext的源代码,做一下处理。
接着是枚举class.js中的类了,先通过ns方法生成类的命名空间,然后根据小数点拆分一下类名,取得源对象和目的对戏,然后根据isObject确认对象是实例还是非实例,进行相应的处理。
最后是把VS对象内的Ext对象和ClassManager对象内的别名对照表转换为文本,输出到页面。
在浏览器中打开页面,将看到一个JSON格式的输出文本,全选该文本,然后复制到一个名称为Ext.js的文件内,这样,通过该文件就可在VS内实现智能提示了。
要使用把Ext.js,首先将文件复制到项目中。然后根据编辑的文件类型采用不同的方法。
如果是单独的脚本(扩展名为js)文件,在脚本文件头部加入以下语句:- /// <reference path="[相对路径]/Ext.js" />
/// <reference path="[相对路径]/Ext.js" />
这里一定要注意路径,如果要编辑的脚本文件与Ext.js文件路径相同,语句为:
- /// <reference path="Ext.js" />
/// <reference path="Ext.js" />
最简单直接的方法,就是在解决方案资源管理器中把Ext.js文件直接拖动到编辑的脚本文件中,会自动生成该语句。
有了该语句后,输入“Ext.”就可以看到如图2所示的智能提示了。
如果找不到ext.jsb2文件(ExtJS4好像以新方法提供,一般情况下没有该文件),也可以使用1.4.2节中生成的Ext.js文件,笔者测试过,效果是一样的。
-
13楼
blandness 2013-11-21 21:36发表 [回复] [引用] [举报]
-
-
你好版主,最近买了你的书学习EXT,按照你的方法我把弄好的EXT.js放到项目中可以自动提示了。但是调试的时候报错 网
消息: 'Ext.perf.Monitor' 为空或不是对象
消息: 'Ext.cache' 为空或不是对象
URI: http://localhost:4464/WebSite2/ExtJS/ext-all.js
把EXT.js 放到 ext-all.js文件 前面 和 后面 都报错 怎么解决呢
-
12楼
tanguilong_lion 2013-07-10 14:57发表 [回复] [引用] [举报]
-
-
哪里能下载到class.js呀,我找不到呢?
-
Re:
上将军 2013-07-10 15:06发表 [回复] [引用] [举报]
-
-
回复tanguilong_lion:书的资源包里有。
-
Re:
tanguilong_lion 2013-07-11 06:40发表 [回复] [引用] [举报]
-
-
回复tianxiaode:我只有书,没有光盘,您附录中的“简写类名与Ext JS 类名对照表”大概有10页,我要手动编写类似 var classList= ['Ext.layout.container.Absolute', 'Ext.layout.container.AbstractCard', 'Ext.AbstractCmponent', 'Ext.AbstractManager']; 这个列表才行吗?我还想问您一下,我现在用的Ext4.2版本,用这个方式生成智能提示也是可行的吗?
-
Re:
上将军 2013-07-11 10:41发表 [回复] [引用] [举报]
-
-
回复tanguilong_lion:一样的,在我微博的微盘里有下载http://vdisk.weibo.com/?leftnav=1&wvr=5&loc=newapp
-
Re:
tanguilong_lion 2013-07-11 23:35发表 [回复] [引用] [举报]
-
-
回复tianxiaode:唉,太难找了,微博里那么多共享文件,也不知道哪个是啊
-
Re:
tanguilong_lion 2013-07-11 23:50发表 [回复] [引用] [举报]
-
- 回复tanguilong_lion:哦,csdn里有人发布了资源包的下载源!
-
-
-
-
-
-
11楼
Mr_ALei 2013-05-24 12:15发表 [回复] [引用] [举报]
-
-
老师,问你个问题
http://bbs.youkuaiyun.com/topics/390468087?page=1#post-394585282
没人解答,老师,帮帮忙,谢谢了
-
10楼
aspvfp 2012-12-21 12:16发表 [回复] [引用] [举报]
-
- 真的不负责 哎 搞的我到处找class.js 还以为是 ext下的 src\core\src\class\class.js 无果 然后上午搜 才发现这个博客. 然后再去网站上下代码.. 每秒1k ... 要下几个小时. 为什么不能注明一下 哎 注明一下今天刚看到第二章
-
8楼
wsi49662531 2012-09-21 10:23发表 [回复] [引用] [举报]
-
- 老师 为什么属性不提示?
-
7楼
wsi49662531 2012-09-21 09:38发表 [回复] [引用] [举报]
-
- 楼主何不放出class.js 以供晚辈学习,实在的 能力不足以整理出class.js 高手容易低手难啊
-
5楼
minide5928 2012-08-27 23:29发表 [回复] [引用] [举报]
-
- <script type="text/javascript" src="class.js"></script> 个类还是没有找到咋个生成…… 希望老师指点啊?
-
4楼
qazwsx111qqq 2012-08-21 16:53发表 [回复] [引用] [举报]
-
- 啊啊啊!!怎么看起来好像老师这本书都像在贴代码啊??如果给代码付多点说明就好了,毕竟新手还是多啊,如果能像陈雄华老师的《spring 3.x企业应用开发实战》这本书就好了,,解释多,易懂
-
3楼
feng12312356 2012-08-07 19:48发表 [回复] [引用] [举报]
-
- 请问 class.js 里面的内容是什么?
-
2楼
hya0114145 2012-07-05 17:36发表 [回复] [引用] [举报]
-
-
其中Ext.Array.each(classList,function(classname){ 代码
中的classList从哪来
-
1楼
hya0114145 2012-07-05 17:33发表 [回复] [引用] [举报]
-
- 请问下枚举class.js中的类指的是哪里的文件