我们写过了一个测试程序:test.js,其中用到了Ext.onReady();
Ext.onReady:这个方法是Ext的准备函数,也就是Ext相关的代码都会在这个函数里书写,它比较类似于window的onload方法,但是注意其执行时机是在页面的DOM对象和ExtJs库文件加载完毕之后立即执行。
关于Ext.onReady,只有在Ext框架全部加载完后才能在客户端的代码中使用Ext,而Ext的onReady正是用来注册在Ext框架及页面的html代码加载完后,所要执行的函数。
调用onReady方法时可以带三个参数,
第一个参数是必须的,表示要执行的函数或匿名函数,
第二参数表示函数的作用域,
第三个参数表示函数执行的一些其它特性,比如延迟多少毫秒执行等,大多数情况下只需要第一个参数即可。
比如示例代码会在页面加载后执行函数a,弹出"Everything is ready."的提示信息。
Javascript代码
function a(){
alert("Everything is ready.");
}
Ext.onReady(a);
可以在一个页面中多次调用onReady方法,则将会把这些方法放到事件队列中,依次执行;onReady的第三个参数是事件执行的一些特殊属性描述,可以是简单的true或false,也可以是一个对象,对象中可以包含delay、single、buffer等属性,比如在上面的代码中添加下面的代码:
Javascript代码
Ext.onReady(function(){alert("2")},this,{delay:5000});
则在页面加载完成后,执行了a方法中的内容,5秒后会执行上面onReady方法中的匿名函数。
作用域是javascript中一个比较关键的特性,我们可以在事件中执行某一个函数的执行的作用域,下面的代码演示了在onReady方法中使用作用域。
Java代码
var b1={v:"this is b1"};
var b2={v:"this is b2"};
function b()
{
alert(this.v);
}
Ext.onReady(b,b1);
Ext.onReady(b,b2);
上面的代码直接调Ext类的onReady方法指定在页面加载完后执行函数b,函数b中的代码是输出当前对象的v属性值,执行这段代码可以看到onReady中作用域的效果。
先显示this is b1,然后显示this is b2
再看一个例子:
function f(){
Ext.Msg.show({
title:'Hello',
msg:'Have you seen my heart?',
buttons:{
yes:'true',
no:true,
cancel:true,
}
});
}
Ext.onReady(f());
想通过这种方式调用函数,结果无法显示,对于onReady,有三种使用方式:
方式一:
<script>
Ext.onReady(function(){
alert('onready');
});
</script>
最直接的一种。
方式二:
<script>
Ext.color=function(){
return{
init:function(){
alert("init");
}
}
}();
Ext.onReady(Ext.color.init,Ext.color);
</script>
通过onReady调用color函数,init为color中的内置,作用是初始化.这种写法比较实用
方式三:
<script>
Ext.onReady(function(){
alert('onready');
});
Ext.color=function(){
return{
init:function(){
alert("init");
}
}
}();
Ext.onReady(Ext.color.init,Ext.color);
</script>
这种是混合型写法,两个onReady都会被调用,调用顺序是看谁在前面.
现在开始hello world的编写:使用Ext.window.MessageBox:这个类提供了ExtJS的弹出提示框、确认框等简单的小组件。我们首先根据它写出我们的Helloworld.
关于ExtJs的帮助文档:Ext API,看下面的图:
有几种不同的图标,各自代表不同的含义:
红立方体代表单例(单体)
,这个图标代表是一个包
蓝色立方体代表一个类
齿轮代表一个组件,可以使用xtype:button来引用
关于singleton和前面的Ext.color=function(){}():
有一篇文章如下:shocking2001的博客
Extjs 发展至今,传承了YUI的伟大精髓, YUI得到了Douglas Crockford(任职于 Yahoo! 的一名 JavaScript 传道者和架构师,他是全球最有造诣的 JavaScript 语言专家之一,Blog:http://www.crockford.com/) 大师的赞同,而ExtJS也是将YUI的模式脚本编程学习使用的淋漓尽致,并且还给它做了几套华丽的CSS嫁衣…., 而在ExtJS越发耀眼的同时,我等初学者在使用ExtJs的时候也是晕呼其呼。(好在2.0 推出之后,官方的文档,像雨后春笋一样,开始覆盖到方方面面。)
其实,拨开ExtJS华丽的外衣,翻阅其体内精致的代码,不难发现一些我们耳熟能详的设计模式。
在早期1.0,1.1的好多例子中,我们会看到这样风格的代码。
var Oo= function(){ var x; var y; return{ a:function(){ ... }, b:function(){ ... } }}();
咂一看,不是我们能理解的方式, function(){}(), 是何意?。
//()在这里,意味着方法已经执行,并且return里面的已经产生, 这样可能很难理解,那等同与执行 function oo(){},这样是否好理解些了?
BTW :这里要引入JavaScript的一个高级概念,“闭包”。(具体内容参考《JavaScript The Definitve Guid,5th Eddion》Section 8.8 –Function Scope and Closures ,也是被Douglas Crockford推荐的为数不多的两本书籍之一。), 当然不急着去翻,先把我的废话看完。
好了,看这种使用别扭的使用方式, 而这种方式,在我们的页面,或者其他类中, 调用Oo的a方法的时候,形式如下
Ext.onReady(Oo.a);
对,正是这样的一种JS编程方式,被Douglas Crockford作为JS的一种单例的实现, 大师还把它叫做“Module Pattern”,
好,如果我们不用所谓单例呢?, 就看看传统的对象方式,同学们肯定在Pototype盛行的时代,已经弄的一清二楚。
0o = function(){ this.x; this.y;}Oo.prototype = { a:function(){ this.x = 100; }, b:function(){ this.y = 200; }}//调用方式Ext.onReady(function(){ var o = new Oo(); 0.a();});
再来,假使是个初学者,不知道对象继承,怎么办。更土的写法,人人都会。
var x,yfunction a(){ x=100;}function b(){ y=200;}
调用方式。
不用说了,只要a(),就会把x设置, 全世界的开发者都公认 ,全局变量是邪恶的,,而且随着你调用的不注意,将会越来越臃肿,导致Memory Lacks 内存泄露。
以上几个简单的举例可以看出, 类 比Java 一样, Oo.a直接调用,好比一个静态类,直接访问。 而prototype需要创建对象后访问其成员。
第一种方式,在任何地方都不需要创建(只创建一次),
而第二种方式,需要在每次调用的时候,创建对象。
第三种老土的代码,希望大家尽量少写,这不是程序员风格的体现。
对于发展到今天,如此庞大的ExtJS2.0,自然也要考虑道自己的运行和调用不要让new 变得太臃肿,在ExtJS中我们发现, 在会被各个组件大量频繁调用到的一些工具类中,单例运用较为频繁。
Ext 源码中,设计使用单利的代码片段。
//source/core/DomHelper.jsExt.DomHelper= function() { //private attributes .. return{}}();//source/core/DomQuery.jsExt.DomQuery =fucntion(){}();
后记: 由于JavaScript,具有prototype,call,apply来实现继承,面向对象来开发,又有闭包等特性来进行函数编程。有函数编程和面向对象的双重性质, 使得JavaScript格外的灵活,难以驽驾, 开发者选择多种风格来进行编码,在一个整体项目会容易会走向凌乱和灭亡。 这就更需要我们从大师的经验总结,以及ExtJS这种优秀的设计中,去体味学习,站在巨人的肩膀上前进…..
(另外值得一提出的,ExtJs必须要求你的页面为XHTML,当你在别的浏览器下跑的非常顺畅,而唯独IE下有那么点瑕疵(不是脚本报错的),你应当检查下你是否把你的页面定义成XHTML.)。
开始最简单测试程序:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'hello.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
<span style="color:#ff0000;"><link rel="stylesheet" type="text/css" href="js/ExtJs/resources/css/ext-all.css">
<script type="text/javascript" charset="utf-8" src="js/ExtJs/bootstrap.js"></script>
<script type="text/javascript" charset="utf-8" src="js/ExtJs/ext-lang-zh_CN.js"></script>
<script type="text/javascript" charset="utf-8" src="base/hello.js"></script></span>
</head>
<body>
This is my JSP page. <br>
</body>
</html>
hello.js:
Ext.onReady(function(){
Ext.MessageBox.alert("我是标题","helloworld!",function(){
console.info(this);
alert("我是回调函数!");
},this);
});
关于Ext.MessageBox的alert()方法,有四个参数,第一个是标题信息,第二个是提示内容信息,第三个是一个回调函数(可选),第四个是作用域(可选)。关于回调函数,就是方法执行完毕后在调用的函数,如上面的执行:
这时还不是执行完毕,当我们点击了确定按钮或是点击关闭,才算执行完毕,这时会调用function(){},就是先在控制台输出this的信息,然后再显示一个alert窗口。
控制台的输出信息(console.info(this)): Window {top: Window, window: Window, location: Location, external: Object, chrome: Object…}
还可以使用Ext.Msg,如Ext.Msg.alert('标题','extjss!!!');Msg与MessageBox是相同的,是简写。
要注意的是,Ext.MessageBox的alert()并不是真正的一个alert(),只是一个模拟alert()效果的div。真正的alert窗口是一个模态窗口。
Ext.MessageBox是一个工具类,提供了各种风格的信息提示对话框,也可以简写为Ext.Msg,这在Ext中很常见,很多组件或类都可以使用简写形式。
- alert方法
- confirm方法
- prompt方法
- wait方法
- show方法
实例:
Ext.onReady(function(){
//提示框
// Ext.MessageBox.alert("我是标题","helloworld!",function(){
// console.info(this);
// alert("我是回调函数!");
// },this);
//
// Ext.Msg.alert('标题','extjss!!!');
//询问框
// Ext.Msg.confirm('title!-zdy','contents-zdy确定还是取消?!',function(op){
//op就是我们点击confirm的两个按钮后的返回值,有yes和no
// if(op == 'yes'){
// alert('确定了');
// } else {
// alert('取消了');
// }
// });
//输入框
// Ext.Msg.prompt('title-zdy','请输入姓名',function(op,val){
//op 有两个值:ok或cancel
// console.info(op);
// console.info(val);
// },this,true,'张三');
//如果输入张三111,点击确定,控制台输出是:ok 张三111
//如果输入张三222,点击取消,控制台输出是:cancel 张三222
//等待框 wait的参数,三个:msg, [title], [config],config是一个 Ext.ProgressBar.wait
// Ext.Msg.wait('提示信息','标题',{
// interval: 500, //循环定时的间隔
// duration: 7000,//总时长
// increment: 15, //执行进度条的次数
// text: '更新中,请稍后...', //进度条提示信息
// scope: this,
// fn: function(){ //回调函数
// alert('执行成功');
// },
// animate:true //动画渲染,平滑展示
// });
//show方法
Ext.Msg.show({
title:'我自定义的提示框',
msg:'提示的内容',
width:300,
height:100,
buttons:Ext.Msg.YESNOCANCEL,
icon:Ext.Msg.WARNING //ERROR\INFO\QUESTION\WARING,显示的图标
});
});