搜档网
当前位置:搜档网 › ext入门学习

ext入门学习

ext入门学习
ext入门学习

Ext入门学习

一:Ext是什么

ExtJS是一个javascript框架,用于在客户端创建丰富多彩的web应用程序界面。ExtJS 可以用来开发RIA也即富客户端的AJAX应用。

ExtJs最开始基于YUI技术,由开发人员Jack Slocum开发,通过参考Java Swing等机制来组织可视化组件。

二:Ext能干什么

主要是用来制作富客户端的Web应用。包括但不限于:

(1)可以动态创建web组件,动态维护web的Dom对象

(2)灵活地获取界面组件对象,方便对对象的操作和控制

(3)大量的组件对象帮助构建复杂的web应用

(4)友好的Ajax支持

(5)完善的事件处理机制

三:Ext有什么

四:Ext的HelloWorld

1:环境准备

(1)到官网上下载最新的版本,目前是ext-3.3-beta

(2)下载后解压后,看看里面的包结构:

adapter:负责将里面提供的第三方底层库(包括Ext自带的底层库)映射为Ext所支持的底层库。

build:压缩后的ext全部源码(里面分类存放)。

docs: API帮助文档。

exmaples:提供使用ExtJs技术做出的小实例。

resources:Ext UI资源文件目录,如CSS、图片文件都存放在这里面。

package:按包分类的源码

source:无压缩Ext全部的源码(里面分类存放) 遵从Lesser GNU (LGPL)开源的协议。Ext-all.js:压缩后的Ext全部源码。

ext-all-debug.js:无压缩的Ext全部的源码(用于调试)。

ext-core.js:压缩后的Ext的核心组件,包括sources/core下的所有类。

ext-core-debug.js:无压缩Ext的核心组件,包括sources/core下的所有类。

(3)开发的时候只需要把resources包中的css和images放到common下面,还有把ext-all.js和adapter/ext/ext-base.js放入到js中就可以了

2:HelloWorld.html

五:Ext的面向对象简介

//相当于Java的package

https://www.sodocs.net/doc/376585440.html,space("https://www.sodocs.net/doc/376585440.html,");

//完全使用Ext的创建对象语法太繁琐,还是用我们熟悉的js的语法来写

https://www.sodocs.net/doc/376585440.html,.Class1=function(){

this.aa = "cc";

this.t1=function(){

this.aa="t1";

};

};

https://www.sodocs.net/doc/376585440.html,.Class2=function(){

this.t1=function(){

this.aa="cc2 tt2";

};

};

//表示Class2继承Class1,这里面没有采用Ext的extends

https://www.sodocs.net/doc/376585440.html,.Class2.prototype=new https://www.sodocs.net/doc/376585440.html,.Class1();

//或者使用这个Ext提供的语法

//Ext.extend(https://www.sodocs.net/doc/376585440.html,.Class2,https://www.sodocs.net/doc/376585440.html,.Class1);

//这个是Ext可以给一个对象动态的追加属性和方法

Ext.apply(https://www.sodocs.net/doc/376585440.html,.Class1.prototype,{bb:"bb",cc:"cc",dd:function(){alert("ddd")}} );

六:如何获取界面上的元素——Ext的选择器

1:Ext.Element:Ext的核心对象,是Ext的基础。

Element包含了常见的DOM方法和属性,提供一个快捷的、统一的、跨浏览器的接口(若使用Element.dom的话,就可以直接访问底层DOM的节点。);

2:Ext.get(要获取对象的id)

Element.get()方法提供内置缓存(Cache),多次访问同一对象效率上有极大优势;

内置常用的DOM节点的动作,并且是跨浏览器的定位的位置、大小、动画、拖放等等(添加/移除 CSS 类, 添加/移除事件处理程序, 定位, 改变大小, 动画, 拖放)。

3:获取多个元素——DomQuery

(1)元素选择符selector:

Ext.query(元素类型名称如:”div”);

Ext.query(第一个参数元素类型名称,第二个参数是#元素的id);

Ext.query(#元素的id);

Ext.query(.元素的class);

Ext.query(*号返回所有的元素);

Ext.query("div input")//获取div下的子元素

(2)属性选择符

Ext.query("*[class]")//获取所有有class属性的元素

Ext.query("*[class=hello] )"//获取所有class=hello的元素

Ext.query("*[class!=hello]" )// 获取所有class不等于hello的元素

Ext.query("*[class^=h]" )// 获取所有以h开头的元素

Ext.query("*[class$=h]" )// 获取所有以h结尾的元素

Ext.query("*[class*=hello]" )// 获取所有包含hello的元素

(3)CSS值元素选择符

语法格式:元素{CSS的属性操作符值}

Ext.query("*{color=red}")//获取Css属性中color为red的元素

操作符同样可以是:!=,^,$,*等

(4)伪类选择符

Ext.query("span:first-child"); // SPAN元素为, 其父元素的第一个子元素

Ext.query("a:last-child") //A元素为其父元素的最后一个子元素

Ext.query("span:nth-child(2)") //SPAN元素为其父元素的第2个子元素(由1开始的个数)

Ext.query("tr:nth-child(odd)") //TR元素为其父元素的奇数个数的子元素

Ext.query("li:nth-child(even)") //LI元素为其父元素的偶数个数的子元素

Ext.query("a:only-child") //返回A元素,A元素为其父元素的唯一子元素

Ext.query("input:checked") //返回所有选中的(checked)的INPUT元素

Ext.query("tr:first") //返回第一个的TR元素

Ext.query("input:last") //返回最后一个的INPUT元素

Ext.query("td:nth(2)") //返回第二个的TD元素

Ext.query("div:contains(within)") //返回每一个包含“within”字符串的DIV

Ext.query("div:not(form)") //返回没有包含FORM子元素以外的那些DIV

Ext.query("div:has(a)") //返回包含有A元素的那些DIV集合

Ext.query("td:next(td)") //返回接着会继续有TD的那些TD集合。尤其一个地方是,如果使用了colspan属性的TD便会忽略

Ext.query("label:prev(input)")//返回居前于INPUT元素的那些LABEL元素集合

Ext.query和Ext.select的作用同是根据CSS选择符,基本的XPath,HTML属性等查找出一个或多个元素。区别在于返回类型上。分别是:

query方法返回的是JavaScript标准的数组类型;

select方法返回的是CompositeElement类型,试比较

七:响应事件

Ext.get("btn_add").on("click",function(){alert("哈哈,点击了");});

添加事件方式跟JQuery类似。

如何得知这个event handler执行时是作用在哪一个特定的元素上呢?自动传入event: Ext.get("btn_add").on("click",function(e){alert("哈哈,点击了=="+e.target.value);});

八:数据操作

Store、Record、Reader等

Store是在Js端的小型内存数据中心,js组件从store里面取值

Record是记录,主要就是描述store里面每一条值,基本是key-value

Reader是解析器,就是从原始数据读成需要的对象。

比如:var sexStore = new Ext.data.JsonStore({

url: "a.jsp",

fields: [

'sexTrue', 'sexShow'

],

listeners: {

'load': function(){ alert("now load"); }

}

});

sexStore.load();

后台返回的值:

<%@ page contentType="text/html; charset=gb2312" %>

<%

out.println("[{sexTrue:'1',sexShow:'男人'},{sexTrue:'2',sexShow:'女人'}]"); %>

九:使用组件——Widgets

1:Ext.Button

(1)//初始化

var btn_add = new Ext.Button({

//设置属性

text:"新增",

//显示出来

renderTo:Ext.getBody()

});

(2)//显示按钮的属性,要注意这个text和上面的text在Ext里面不同,上面那个是Config,用在构造对象的时候,这个是属性,用来取值用

alert(btn_add.text);

(3)添加事件:

var btn_add = new Ext.Button({

text:"新增",

renderTo:Ext.getBody(),

handler:function(){

alert("哈哈,点击我");

}

});

handler :用于处理默认的事件,button就是click

还有一种跟swing一样的机制,listeners:

var btn_add = new Ext.Button({

text:"新增",

renderTo:Ext.getBody(),

handler:function(){

alert("哈哈,点击我");

},

listeners:{

"click":function(){

alert("now is click11");

},

"click":function(){

alert("now is click22");

},

"afterrender":function(){

alert("afterrender");

}

}

});

A:可以在listeners里面添加很多事件注册

B:相同的事件,后面的覆盖掉前面的,但不影响handler的触发

还有一种写法:

var btn_add = new Ext.Button({

text:"新增",

minWidth:100,

renderTo:Ext.getBody(),

handler:function(){

alert("哈哈,点击我");

},

listeners:{

"click":function(){

alert("now is click11");

},

"click":function(){

alert("now is click22");

},

"afterrender":function(){

alert("afterrender");

}

}

});

btn_add.on("click",function(){alert("now is click333");});

btn_add.on("click",function(){alert("now is click444");});

A:可以添加很多个,相同的也没有关系,都会运行,形成一个事件链B:可以和handler、listeners共存

2:Ext.form.TextField

Ext.onReady(function(){

var btn_add = new Ext.Button({

text:"新增",

renderTo:Ext.getBody()

});

btn_add.on("click",function(){

alert("now is click444=="+userId.getValue());

}

);

var userId = new Ext.form.TextField({

fieldLabel:"用户编号",

renderTo:Ext.getBody()

});

});

A:会发现:虽然出现了文本框,而且可以操作,点击按钮也能取得文本框的值,但是前面的标签并没有出来,原因是没有使用布局,layout。

这里应该使用https://www.sodocs.net/doc/376585440.html,yout.FormLayout,布局的宿主对象必须是Ext.Container或者其子类。B:只要在构造对象的时候,在宿主对象上指定layout:”form”就好了。

C:Ext.Container的子类主要有:Panel, Toolbar, Viewport, Menu

所以修改成如下:

Ext.onReady(function(){

var btn_add = new Ext.Button({

text:"新增"

});

btn_add.on("click",function(){

alert("now is click444=="+userId.getValue());

userId.setValue("updateddd");

}

);

var userId = new Ext.form.TextField({

fieldLabel:"用户编号",

id:"userId"

});

var addPanel = new Ext.Panel({

renderTo:Ext.getBody(),

layout:"form",

labelWidth:70,

listeners:{

"render":function(addPanel){

addPanel.add(userId);

addPanel.add(btn_add);

}

}

});

});

A:跟swing中一样,用panel来组织页面,其他组件就不需要renderto了

B:取值赋值使用getValue和setValue

3:Ext.panel

完全模拟Swing中的写法

Ext.onReady(function(){

//定义组件

var btn_add = new Ext.Button({

//设置属性

text:"新增"

});

//设置事件

btn_add.on("click",function(){

alert("now is click444=="+Ext.get("userId").getValue());

userId.setValue("updateddd");

}

);

//定义组件

var userId = new Ext.form.TextField({

fieldLabel:"用户编号",

id:"userId"

});

//定义面板

var addPanel = new Ext.Panel({

layout:"form",

width:300,

height:400,

labelWidth:70

});

//把组件放到panel里面

addPanel.add(userId);

addPanel.add(btn_add);

//把panel放到body里面显示出来

addPanel.render(Ext.getBody());

});

A:也可以使用xtype的特性来简化代码,如下:

addPanel.add({xtype:"textfield",fieldLabel:"用户名称"});

B:Ext为了简化代码,使下载量变小,提供了items和buttons,如下:

Ext.onReady(function(){

var addPanel = new Ext.Panel({

layout:"form",

width:300,

height:400,

labelWidth:70,

title:"用户新增界面",

renderTo:Ext.getBody(),

items:[

{

xtype:"textfield",

fieldLabel:"用户编号",

id:"userId"

},

{

xtype:"textfield",

fieldLabel:"用户姓名",

id:"userName"

}

],

buttons:[

{

xtype:"button",

text:"新增",

listeners:{

"click":function(){

alert("now add==="+Ext.get("userId").getValue());

}

}

},

{

xtype:"button",

text:"取消"

}

]

});

});

常见布局

所谓布局就是指容器组件中子元素的分布、排列组合方式。Ext的所有容器组件都支持而局操作,每一个容器都会有一个对应的布局,布局负责管理容器组件中子元素的排列、组合及渲染方式等。

ExtJS的布局基类为https://www.sodocs.net/doc/376585440.html,yout.ContainerLayout,其它布局都是继承该类。

Ext中的一些容器组件都已经指定所使用的布局,比如TabPanel使用card布局、FormPanel 使用form布局,GridPanel中的表格使用column布局等,我们在使用这些组件的时候,不能给这些容器组件再指定另外的布局。常用的布局有border、column、form、card、table等布局。

Form布局

前面已经用了

Column布局

用来实现左右分的,也就是实现一行排多个,如下示例:

Ext.onReady(function(){

var addPanel = new Ext.Panel({

layout:"form",

width:600,

height:400,

labelWidth:70,

title:"用户新增界面",

renderTo:Ext.getBody(),

items:[

{

layout:"column",

items:[

{

columnWidth:.5,

layout:"form",

items:[

{

xtype:"textfield",

fieldLabel:"用户编号",

id:"userId"

},

{

xtype:"textfield",

fieldLabel:"用户姓名",

id:"userName"

}

]

},

{

columnWidth:.5,

layout:"form",

items:[

{

xtype:"textfield",

fieldLabel:"用户年龄",

id:"userAge"

},

{

xtype:"textfield",

fieldLabel:"用户性别",

id:"sex"

}

]

}

]

}

],

buttons:[

{

xtype:"button",

text:"新增",

listeners:{

"click":function(){

alert("now login==="+Ext.get("userId").getValue());

}

}

},

{

xtype:"button",

text:"取消"

}

]

});

});

Border布局

Border布局由类https://www.sodocs.net/doc/376585440.html,yout.BorderLayout定义,布局名称为border。该布局把容器分成东南西北中五个区域,分别由east,south, west,north, center来表示,在往容器中添加子元素的时候,我们只需要指定这些子元素所在的位置,Border布局会自动把子元素放到布局指定的位置。看下面的代码:

Ext.onReady(function(){

new Ext.Viewport({

layout:"border",

items:[

{

region:"north",

height:50,

title:"顶部面板"

},

{

region:"south",

height:50,

title:"底部面板"

},

{

region:"center",

title:"中央面板"

},

{

region:"west",

width:100,

title:"左边面板"

},

{

region:"east",

width:100,

title:"右边面板"

}

]

});

});

Accordion布局(可折叠布局)

Ext.onReady(function(){

new Ext.Panel({

renderTo:"hello",

title:"容器组件",

width:500,

height:200,

layout:"accordion",

layoutConfig: {

animate: true

},

items:[

{

title:"子元素1",

html:"这是子元素1中的内容"

},

{

title:"子元素2",

html:"这是子元素2中的内容"

},

{

title:"子元素3",

html:"这是子元素3中的内容"

}

]

});

});

Card布局

Ext.onReady(function(){

var panel=new Ext.Panel({

renderTo:"hello",

title:"容器组件",

width:500,

height:200,

layout:"card",

activeItem: 0,

layoutConfig: {

animate: true

},

items:[

{

title:"子元素1",

html:"这是子元素1中的内容"

},

{

title:"子元素2",

html:"这是子元素2中的内容"

},

{

title:"子元素3",

html:"这是子元素3中的内容"

}

],

buttons:[

{

text:"切换",handler:changeTab

}

]

});

var i=1;

function changeTab(){

panel.getLayout().setActiveItem(i++);

if(i>2){

i=0;

}

}

});

Table布局

Ext.onReady(function(){

var panel=new Ext.Panel({

renderTo:"hello",

title:"容器组件",

width:500,

height:200,

layout:"table",

layoutConfig: {

columns: 3

},

items:[

{

title:"子元素1",

html:"这是子元素1中的内容",

rowspan:2,

height:100

},

{

title:"子元素2",

html:"这是子元素2中的内容",

colspan:2

},

{

title:"子元素3",

html:"这是子元素3中的内容"

},

{

title:"子元素4",

html:"这是子元素4中的内容"

}

]

});

});

4:Ext.window

Ext.onReady(function(){

var addPanel = new Ext.Window({

layout:"form",

width:600,

height:400,

labelWidth:70,

title:"用户新增界面",

renderTo:Ext.getBody(),

items:[

{

layout:"column",

items:[

{

columnWidth:.5,

layout:"form",

items:[

{

xtype:"textfield",

fieldLabel:"用户编号",

id:"userId"

},

{

xtype:"textfield",

fieldLabel:"用户姓名",

id:"userName"

}

]

},

{

columnWidth:.5,

layout:"form",

items:[

{

xtype:"textfield",

fieldLabel:"用户年龄",

id:"userAge"

},

{

xtype:"textfield",

fieldLabel:"用户性别",

id:"sex"

}

]

}

]

}

],

buttons:[

{

xtype:"button",

text:"新增",

listeners:{

"click":function(){

alert("now login==="+Ext.get("userId").getValue());

}

}

},

{

xtype:"button",

text:"取消"

}

]

});

addPanel.show();

Ext.get("btn_add").on("click",

function(){

if(addPanel.isVisible()){

addPanel.hide();

}else{

addPanel.show();

}

}

);

});

5:Ext.form.DateField

设置xtype:"datefield",

年月日的格式参照文档,比如:format:"Y-m-d",

6:https://www.sodocs.net/doc/376585440.html,boBox

设置xtype:"combo",

要给combobox赋值,需要使用Store,相当于在js里面的一个内存数据库,也就是取值的地方。

xtype:"combo",

fieldLabel:"用户性别",

id:"sex",

mode:"local",

displayField:"sexShow",

valueField:"sexTrue",

store: new Ext.data.ArrayStore({

fields: [

'sexTrue','sexShow'

],

data: [['1','男'], ['2','女']]

})

A:要想后台获取Combobox的真实值,需要设置hiddenName,

B:如果想要不让它自动查询,只要设置triggerAction:?all?

C:可以给combobox设置分页,只需要设置:pageSize:5 ,minListWidth:100,此时的Mode 必须为remote,具体要不要分页,由ext内部决定

D:如果要combox不能输入值,那么就设置readonly为true就可以了

7:Ext.form.FormPanel

对于经常需要跟后台交互的panel可以选用formPanel,它是panel的子类,默认的提交方式是基于ajax的,可以修改成为标准的提交方式:

Ext.onReady(function(){

var addPanel = new Ext.FormPanel({

layout:"form",

width:600,

height:400,

labelWidth:70,

title:"用户新增界面",

renderTo:"myFormDiv",

standardSubmit:true,

method:"post",

url:"a.jsp",

items:[

{

layout:"column",

items:[

{

columnWidth:.5,

layout:"form",

items:[

{

xtype:"textfield",

fieldLabel:"用户编号",

id:"userId",

name:"userId"

},

{

xtype:"textfield",

fieldLabel:"用户姓名",

id:"userName",

name:"userName"

}

]

},

{

columnWidth:.5,

layout:"form",

items:[

{

xtype:"datefield",

format:"Y-m-d",

fieldLabel:"用户年龄",

id:"userAge"

},

{

xtype:"combo",

fieldLabel:"用户性别",

id:"sex",

mode:"local",

valueField:"sexTrue",

displayField:"sexShow",

store: new Ext.data.SimpleStore({

fields: [

'sexTrue','sexShow'

],

data: [['1','男'], ['2','女']]

})

}

]

}

]

}

],

buttons:[

{

xtype:"button",

text:"新增",

listeners:{

"click":function(){

addPanel.getForm().getEl().dom.action=addPanel.url;

addPanel.getForm().submit();

}

}

},

{

xtype:"button",

text:"取消"

}

]

});

});

如果采用默认的ajax提交的方式,可以如下:

addPanel.getForm().submit({

success:function(form,action){

Ext.Msg.alert(‘信息’,action.result.msg);

}

,

failure:function(){

}

});

此时后台如下返回:

<%=”{success:true,msg:’操作成功’}”%>

Ext.grid.GridPanel

先来最简单的:

Ext.onReady(function(){

var cm = new Ext.grid.ColumnModel([

相关主题