1. extjs4.0对原生javaScript功能进行了扩展(API中的Utilities模块中的NativeExtensions)
Utilities:常用的一些工具处理类
Native Extensions
Ext.Array
Ext.Number
Ext.Object
Ext.String
Ext.JSON
Ext.Date
Ext.Function
具体扩展了那些,请参照具体的API说明,扩展的原理eg:
var Person = {name:'yfc',age:26};
//alert(Person['name']);
//extjs4.0提供getKey的函数
//alert(Ext.Object.getKey(Person,'yfc'));
Object.prototype.getValue = function(key,defValue){
if(this[key]){
return this[key];
}else{
return defValue;
}
}
alert(Person.getValue("email","pcat@126.com"));
//由于给Object的原型加上了一个getValue的函数,这样所有的对象(都继承Object)默认都会拥有这个函数。
2. 事件机制与新特性
(1)给对象加事件:
Ext.get("元素ID").on("click",function(){
//函数处理部分
});
(2)新特性:create与define(extend 、requires、config、mixins、alias以及statics )。
- create:在ExtJs4.0中你可以通过new方式也可以用create的方式得到一个对象的实例,在4.0版本中建议用create的方式来创建实例,这样ExtJS会对创建的实例进行统一管理。
//create第一个参数为类路径,第二个参数为该类的一些初始化参数值(以对象的形式传递)
var win = Ext.create('Ext.window.Window',{
width:400,
height:300,
title:'uspcat'
});
win.show();
- alias:别名的作用,可以把一个对象的内部函数暴漏处理啊,给其他对象直接调用。eg:
var o = {
say : function(){
alert(11111);
}
}
//通过o.say()调用函数
var fn = Ext.Function.alias(o,'say');
fn();//通过别名的方式我们就可以直接调用fn()等于o.say()。
- define:是用来定义一个类的,eg:
//create第一个参数是类的全路径,第二个参数则是类的内容
Ext.define('Bmsys.ml.Window', {
extend:'Ext.window.Window',
title: 'Window',
closeAction: 'hide',
width: 380,
height: 300,
resizable: false,
modal: true,
//定义一些自己的扩展参数
myTitile: 'myWindow',
setTitle: function(){
this.title = this.myTitle;
}
//初始化的方法(类似java中的构造方法)
initComponent: function(){
this.setTitle();
this.callParent(arguments);
}
});
var win = Ext.create('Bmsys.ml.Window',{
titile: 'youWindow';
}
);
win.show();//此时创建出来窗体的标题是myWindow,说明创建时,传入的初始化参数比构造器先执行。
注意:属性只能在define时定义,不能通过win.myHeight = function(){...}添加属性。
- requires: JS的异步加载(按需加载),解决了网络js文件大而造成页面打开慢得问题,只有当成需要用到这个类时Ext才去到后台加载包含这个类的js文件;在这里就要,要求我们在写js类的时候要尽量的模块化,一个类就是一个js文件,而且类名与js文件名一致,命名空间定义规范。
//这时候要启用自动加载
Ext.Loader.setConfig({
enabled:true,
paths:{
myApp:'js/Bmsys/ml' //js文件相对路径,需要与命名空间保持一致
}
});
//这时候只要保证Window.js放在js/Bmsys/ml这个目录下命名空间为Bmsys.ml.Window就可以了。
//这时就不需要在JSP文件中引入Window.js,等到下面的程序被执行时,才会根据命名空间去到后台加载Window.js。
//原理就是通过命名空间与文件路径,拼接好后通过写入<script>标签的方式加载。
var win = Ext.create('Bmsys.ml.Window',{
titile: 'youWindow',
requires: ['Bmsys.ml.Window']
}
).show();
- config: 这个属性就是把你定义类的属性自动的加上get、set方法,省去自己去写的麻烦事。
Ext.define('Bmsys.ml.Window', {
extend:'Ext.window.Window',
title: 'Window',
width: 380,
height: 300,
//定义一些自己的扩展参数
myTitile: 'myWindow',
config: {
myHeight : 800
}
});var win = Ext.create('Bmsys.ml.Window',{});
alert(win.getMyTitle());//报错,没有定义getMyTitle函数
alert(win.getMyHeight());//正常弹出值为800//放在config里面定义的属性,Ext会自动给这个属性加上get、set方法。
- mixins:类的混合(多继承实现),因为我们在用define定义类的时候,extend只能继承一个类。为了拥有其它类定义好的方法及功能,我们可以通过类的混合来实现。
Ext.define("say",{
cansay:function(){
alert("hello");
}
})
Ext.define("sing",{
sing:function(){
alert("sing hello 123");
}
})//通过类的混合,就可以轻松拥有上面两个类里面的函数。
Ext.define('user',{
mixins :{
say : 'say',
sing: 'sing'
}
});var u = Ext.create("user",{});
u.cansay();//say类里面的方法
u.sing();//sing类里面的方法- static:类似java中静态,我们可以定义一些静态的属性以及方法,通过类名'.'的方式来访问。
Ext.define('Computer', {
statics: {
factory: function(brand) {
// 'this' in static methods refer to the class itself
return new this(brand);
}
},
constructor: function() { ... }
});
//直接通过类名'.'的方式访问静态方法
var dellComputer = Computer.factory('Dell');3. 数据模型model(MVC中的M层)数据模型对真实世界中对事物在系统中的抽象,extjs4.0中的mode相当于DB中的table 或 JAVA 中的Class。(1)model的几种创建以及实例的方法。//我们利用Ext.define来创建我们的模型类
//DB table person(name,age,email)
Ext.define("person",{
extend:"Ext.data.Model",
fields:[
{name:'name',type:'auto'},
{name:'age',type:'int'},
{name:'email',type:'auto'}
]
});
//定义的时候,不需要每次写extend:"Ext.data.Model"
Ext.regModel("user",{
fields:[
{name:'name',type:'auto'},
{name:'age',type:'int'},
{name:'email',type:'auto'}
]
});
//实例化我们的person类
//1.new关键字
var p = new person({
name:'uspcat.com',
age:26,
email:'yunfengcheng2008@126.com'
});
//alert(p.get('name'));
var p1 = Ext.create("person",{
name:'uspcat.com',
age:26,
email:'yunfengcheng2008@126.com'
});
//alert(p1.get('age'));
var p2 = Ext.ModelMgr.create({
name:'uspcat.com',
age:26,
email:'yunfengcheng2008@126.com'
},'person');
alert(p2.get('email'));//实例不能直接通过getName得到类名,因为这个方法是类的 class object.getClass.getName
//alert(p2.getName());//通过类.getName可以获得类名,因为person是模型类的定义,而不是实例
(2)model模型Validations以及通过修改原始类来实现自定义验证器。
alert(person.getName());//在校验之前,修改原始类里属性的默认值
Ext.data.validations.lengthMessage = "错误的长度";Ext.onReady(function(){
//通过apply方法来在原始的校验器类上扩展我们自定义验证机制的的一个新的验证方法
Ext.apply(Ext.data.validations,{
//自定义的校验类型函数
age:function(config, value){
var min = config.min;
var max = config.max;
if(min <= value && value<=max){
return true;
}else{
this.ageMessage = this.ageMessage+"他的范围应该是["+min+"~"+max+"]";
return false;
}
},
ageMessage:'age数据出现的了错误'
});
//定义一个带有校验的模型类
Ext.define("person",{
extend:"Ext.data.Model",
fields:[
{name:'name',type:'auto'},
{name:'age',type:'int'},
{name:'email',type:'auto'}
],
validations:[
//type的值就是Ext.data.validations里方法名称
//field是你要校验字段名
//field后面的参数就是名称等于type值的函数的参数。
{type:"length",field:"name",min:2,max:6},
{type:'age',field:"age",min:0,max:150}
]
});
var p1 = Ext.create("person",{
name:'uspcat.com',
age:-26,
email:'yunfengcheng2008@126.com'
});
//通过validate()可以得到数据校验的错误集合
//每个error里面含有两个属性(field---校验字段的名,message---校验函数返回的错误信息)
var errors = p1.validate();
var errorInfo = [];
errors.each(function(v){
errorInfo.push(v.field+" "+v.message);
});
alert(errorInfo.join("\n"));
});注意:自定义的校验器,你可以通过利用apply方法来为原始的类增加,也可以通过继承的方式实现。(3)数据代理proxy:就是通过与后台的交互来完成数据模型,数据填充的服务类。Ext.define("person",{
extend:"Ext.data.Model",
fields:[
{name:'name',type:'auto'},
{name:'age',type:'int'},
{name:'email',type:'auto'}
],
//通过代理从后台获取数据(数据要与model的fields里面的字段相对应)
proxy:{
type:'ajax',
url:'person.jsp'
}
});
var p = Ext.ModelManager.getModel("person");
//通过load方法来触发proxy加载数据
p.load(1, {
scope: this,
//record.data就是加载进来的一个数据实例对象
success: function(record, operation) {
alert(record.data.name)
}
});(4)Molde的一对多和多对一关系。//类老师
Ext.regModel("teacher",{
fideld:[
{name:'teacherId',type:"int"},
{name:'name',type:"auto"}
],
//建立老师与学生的1对多关系
hasMany:{
//所关联的模型
model: 'student',
name : 'getStudent',
//关系字段
filterProperty: 'teacher_Id'
}
});
//学生
Ext.regModel("student",{
fideld:[
{name:'studentId',type:"int"},
{name:'name',type:"auto"},
{name:"teacher_Id",type:'int'}
]
});
//假设t是老师的一个实例,就可以通过t.students 得到子类student的一个store数据集合3. 数据代理Proxy数据代理proxy是进行数据读写的主要途径,通过代理操作数据进行CRUD。CRUD的 每一步操作都会得到唯一的Ext.data.Operation实例,它包含了所有的请求参数。通过构造Ext.data.Operation来传入请求参数。(1)数据代理proxy目录结构Ext.data.proxy.Proxy 代理类的根类(它分为客户端(Client)代理和服务器代理(Server))A、Ext.data.proxy.Client 客户端代理Ext.data.proxy.Memory 普通的内存代理。Ext.data.proxy.WebStorage 浏览器客户端存储代理(cookie操作)。Ext.data.proxy.SessionStorage 浏览器级别代理,浏览器关闭数据消失。Ext.data.proxy.LocalStorage 本地化的级别代理,数据可以保存在浏览器文件里,浏览器关闭后,下次打开还在(不能夸浏览器)。B、Ext.data.proxy.Server 服务器端代理Ext.data.proxy.Ajax 异步加载的方式。Ext.data.proxy.Rest 一种特使的Ajax。Ext.data.proxy.JsonP 跨域交互的代理(请求的数据url不在同域内), 跨域是有严重的安全隐患的,extjs的跨域也是需要服务器端坐相应的配合。Ext.data.proxy.Direct 命令.4. 工作在Proxy下的读写器(1)Reader : 主要用于将proxy数据代理读取的数据按照不同的规则进行解析,讲解析好的数据保存到Model中结构图Ext.data.reader.Reader 读取器的根类Ext.data.reader.Json JSON格式的读取器Ext.data.reader.Array 扩展JSON的Array读取器Ext.data.reader.Xml XML格式的读取器var userData = {
//读写器默认读取的记录总数的属性
//total : 200,
//采用我们自定义的变量来标识总条数,这时后需要在读写器中配置total所对应我们自定义的变量
count:250,
user:[{auditor:'yunfengcheng',info:{
userID:'1',
name:'uspcat.com',
orders:[
{id:'001',name:'pen'},
{id:'002',name:'book'}
]
}}]
};
//model
Ext.regModel("user",{
fields:[
{name:'userID',type:'string'},
{name:'name',type:'string'}
],
//配置一对多的关系
hasMany: {model: 'order'}
});
Ext.regModel("order",{
fields:[
{name:'id',type:'string'},
{name:'name',type:'string'}
],
//配置多对一的关系
belongsTo: {type: 'belongsTo', model: 'user'}
});
var mproxy = Ext.create("Ext.data.proxy.Memory",{
model:'user',
data:userData,
//读写时的参数配置
reader:{
type:'json',//读取的类型(json/xml/array)
root:'user',//指定读取开始的根节点
implicitIncludes:true,//是否级联读取关联的子节点(一对多的关系中体现)
totalProperty:'count',//配置我们返回的总条数变量名称
record : 'info'//服务器返回的数据可能很复杂,用record可以筛选出有用的数据信息,装在带Model中,其它的参数忽略。
}
});
//用内存代理来读取数据,其它的方式一样
mproxy.read(new Ext.data.Operation(),function(result){
var datas = result.resultSet.records;
alert(result.resultSet.total);
Ext.Array.each(datas,function(model){
alert(model.get('name'));
});
var user = result.resultSet.records[0];
var orders = user.orders();
orders.each(function(order){
alert(order.get('name'))
});
})(2)Writer :把前台的js对象数据按照不同的方式写到后台。结构图Ext.data.writer.WriterExt.data.writer.Json 对象被解释成JSON的形式传到后台Ext.data.writer.Xml 对象被解释成XML的形式传到后台Ext.regModel("person",{
fields:[
'name','age'
],
proxy :{//在proxy下,你可以配置reader(读),同样也可以配置writer(写)
type:'ajax',
url:'person.jsp' ,
writer:{//配置一些写的参数
//type:'json'
type:'xml' //把js对象以xml的方式,传入后台
}
}
});
Ext.ModelMgr.create({
name:'uspcat.con',
age:1
},'person').save();5. Store : 是一个存储数据对象Model的集合缓存,它可以为extjs中的可视化组建提供数据源 (GridPanel,ComboBox)等。(在ExtJS中占有重要的地位,它也属于Model层)
(1)类结构Ext.data.AbstractStoreExt.data.Store 没有特殊情况这个类就可以满日常的开发了Ext.data.ArrayStoreExt.data.DirectStoreExt.data.ArrayStore 内置辅助的类Ext.data.JsonStroe 内置辅助的类Ext.data.TreeStore(2)Ext.data.Store 使用参数autoLoad(Boolean/Object) : 自动加载数据,自动调用loaddata(Array) : 内置数据对象的数组,初始化的是就要被装在model(Model) : 数据集合相关的模型fields(Field) :字段的集合,程序会自动生成对于的Model,这样我们就不需要再定义model。方法each( Function f, [Object scope] ) : void 变量数据中的ModelExt.define("person",{
extend:'Ext.data.Model',
fields:[
{name:'name'},
{name:'age'}
],
proxy:{
type:'memory'
}
})
var s = new Ext.data.Store({
//model:'person',
data:[
{name:'uspcat.com',age:1},
{name:'yfc',age:26}
],
//有了fields,我们就不需要在单独定义Model并且引用
fields:[
{name:'name'},
{name:'age'}
],
//通过data属性,请偶们已经能够把数据初始化好了
//proxy是动态的区后台去数据
//proxy:{
// type:'ajax',
// url:'person.jsp'
//}
//autoLoad:true
});
s.load(function(records, operation, success){
//遍历
Ext.Array.each(records,function(model){
alert(model.get('name'));
});
//过滤出字段name='yfc'
s.filter('name',"yfc");
s.each(function(model){
alert(model.get('name'));
});
//通过正则来查找数据集里面的记录,返回该记录的索引
var index = s.find('name','yfc',0,false,true,false);
alert(s.getAt(index));//当前的Model对象
});