ExtJS2.0实用简明教程

ExtJS2.0实用简明教程

 

一、         ExtJS2.0实用简明教程》之ExtJS简介

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

(wlrblog应用)

(ExtJS的表格控件)

(不同主题的ExtJS弹出框效果)

ExtJS是一个用javascript写的,主要用于创建前端用户界面,是一个与后台技术无关的前端ajax框架。因此,可以把ExtJS用在.NetJavaPhp等各种开发语言开发的应用中。   ExtJs最开始基于YUI技术,由开发人员Jack Slocum开发,通过参考Java Swing等机制来组织可视化组件,无论从UI界面上CSS样式的应用,到数据解析上的异常处理,都可算是一款不可多得的JavaScript客户端技术的精品。

二、         ExtJS2.0实用简明教程》之获得ExtJS

要使用ExtJS,那么首先要得到ExtJS库文件,该框架是一个开源的,可以直接从官方网站下载,网址http://extjs.com/download,进入下载页面可以看到大致如图xxx所示的内容,可以选择选择1.12.0版本,本教程使用的2.0版本。

1-1 ExtJs不同版本下载选择页面

单击上图中的【Download ext-2.0.zip】超链接进行下载,把下载得到的ZIP压缩文件解压缩到【D:/ExtCode】目录下,可以得到如如图1-2所示的内容。

1-2 ExtJS发布包目录

adapter:负责将里面提供第三方底层库(包括Ext自带的底层库)映射为Ext所支持的底层库。    build  压缩后的ext全部源码(里面分类存放)    docs  API帮助文档。    exmaples:提供使用ExtJs技术做出的小实例。    resourcesExt UI资源文件目录,如CSS、图片文件都存放在这里面。    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下的所有类。

三、         ExtJS2.0实用简明教程》之应用ExtJS

应用extjs需要在页面中引入extjs的样式及extjs库文件,样式文件为resources/css/ext-all.cssextjsjs库文件主要包含两个,adapter/ext/ext-base.jsext-all.js,其中ext-base.js表示框架基础库,ext-all.jsextjs的核心库。adapter表示适配器,也就是说可以有多种适配器,因此,可以把adapter/ext/ext-base.js换成adapter/jquery/ext-jquery-adapter.js,或adapter/prototype/ext-prototype-adapter.js等。   因此,要使用ExtJS框架的页面中一般包括下面几句:

<link rel="stylesheet" type="text/css" href="extjs/resources/css/ext-all.css" />

 <script type="text/javascript" src="extjs/adapter/ext/ext-base.js"></script>

<script type="text/javascript" src="extjs/ext-all.js"></script>
    
    

ExtJS库文件及页面内容加载完后,ExtJS会执行Ext.onReady中指定的函数,因此可以用,一般情况下每一个用户的ExtJS应用都是从Ext.onReady开始的,使用ExtJS应用程序的代码大致如下: <script type="text/javascript"> function fn() { alert(‘ExtJS库已加’); } Ext.onReady(fn); </script>

<script>

 function fn()

 {

 alert(‘ExtJS库已加’);

 }

 Ext.onReady(fn);

 </script>
     
     

fn也可以写成一个匿名函数的形式,因此上面的代码可以改成下面的形式: <script type="text/javascript"> function fn() { alert(‘ExtJS库已加载!’); } Ext.onReady(function () { alert(‘ExtJS库已加载!’); } ); </script>

<script>

 function fn()

 {

 alert(‘ExtJS库已加载!’);

 }

 Ext.onReady(function ()

 {

 alert(‘ExtJS库已加载!’);

 }

 );

</script>
     
     

四、         ExtJS2.0实用简明教程》之布局概述

所谓布局就是指容器组件中子元素的分布、排列组合方式。Ext的所有容器组件都支持而局操作,每一个容器都会有一个对应的布局,布局负责管理容器组件中子元素的排列、组合及渲染方式等。         ExtJS的布局基类为Ext.layout.ContainerLayout,其它布局都是继承该类。ExtJS的容器组件包含一个layoutlayoutConfig配置属性,这两个属性用来指定容器使用的布局及布局的详细配置信息,如果没有指定容器组件的layout则默认会使用ContainerLayout作为布局,该布局只是简单的把元素放到容器中,有的布局需要layoutConfig配置,有的则不需要layoutConfig配置。看代码:

Ext.onReady(function(){
    
    
new Ext.Panel({
    
    
renderTo:"hello",
    
    
width:400,
    
    
height:200,
    
    
layout:"column",
    
    
items:[{columnWidth:.5,
    
    
title:"面板1"},
     
     
{columnWidth:.5,
    
    
title:"面板2"}]
     
     
});
    
    
});
    
    

上面的代码我们创建了一个面板PanelPanle是一个容器组件,我们使用layout指定该面板使用Column布局。该面板的子元素是两个面板,这两个面板都包含了一个与列布局相关的配置参数属性columnWidth,他们的值都是0.5,也就是每一个面板占一半的宽度。执行上面的程序生成如下图所示的结果:

Ext中的一些容器组件都已经指定所使用的布局,比如TabPanel使用card布局、FormPanel使用form布局,GridPanel中的表格使用column布局等,我们在使用这些组件的时候,不能给这些容器组件再指定另外的布局。         ExtJS2.0一共包含十种布局,常用的布局有bordercolumnfitformcardtabel等布局,下面我们分别对这几种布局作简单的介绍。

五、         ExtJS2.0实用简明教程》之ExtJS版的Hello

下面我们写一个最简单的ExtJS应用,在hello.html文件中输入下面的代码:

<html xmlns="http://www.w3.org/1999/xhtml" >

 <head>

 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

 <title>ExtJS</title>

 <link rel="stylesheet" type="text/css" href="extjs/resources/css/ext-all.css" />

 <script type="text/javascript" src="extjs/adapter/ext/ext-base.js"></script>

 <script type="text/javascript" src="extjs/ext-all.js"></script>

 <script>

 Ext.onReady(function()

 {

 Ext.MessageBox.alert("hello","Hello,easyjf open source");

 });

 </script>

 </head>

 <body>

 </body>

 </html>
    
    

1-11  hello.html页面效果

进一步,我们可以在页面上显示一个窗口,代码如下: <script type="text/javascript"> Ext.onReady(function() { var win=new Ext.Window({title:"hello",width:300,height:200,html:'

Hello,easyjf open source

'}); win.show(); }); </script>

<script>
    
    
Ext.onReady(function()
    
    
{
    
    
var win=new Ext.Window({title:"hello",width:300,height:200,html:'<h1>Hello,easyjf open source</h1>'});
    
    
win.show();
    
    
});
    
    
</script>
    
    

在浏览hello.html,即可得在屏幕上显示一个窗口,如图xxx所示。

六、         ExtJS2.0实用简明教程》之Ext类库简介

ExtJS由一系列的类库组成,一旦页面成功加载了ExtJS库后,我们就可以在页面中通过javascript调用ExtJS的类及控件来实现需要的功能。ExtJS的类库由以下几部分组成: 底层API(core):底层API中提供了对DOM操作、查询的封装、事件处理、DOM查询器等基础的功能。其它控件都是建立在这些底层api的基础上,底层api位于源代码目录的core子目录中,包括DomHelper.jsElement.js等文件,如图xx所示。

控件(widgets):控件是指可以直接在页面中创建的可视化组件,比如面板、选项板、表格、树、窗口、菜单、工具栏、按钮等等,在我们的应用程序中可以直接通过应用这些控件来实现友好、交互性强的应用程序的UI。控件位于源代码目录的widgets子目录中,包含如图xx所示。

实用工具UtilsExt提供了很多的实用工具,可以方便我们实现如数据内容格式化、JSONJavaScript Object Notation)数据解码或反解码、对DateArray、发送Ajax请求、Cookie管理、CSS管理等扩展等功能,如图所示:

七、         ExtJS2.0实用简明教程》之Border区域布局

Border布局由类Ext.layout.BorderLayout定义,布局名称为border。该布局把容器分成东南西北中五个区域,分别由eastsouth, westnorth, cente来表示,在往容器中添加子元素的时候,我们只需要指定这些子元素所在的位置,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:"右边面板"}
     
     

   
   
    
     
   
   
]
    
    

   
   
    
     
   
   
});
    
    

   
   
    
     
   
   
});
    
    

执行上面的代码将会在页面中输出包含上下左右中五个区域的面板,如下图所示:

八、         ExtJS2.0实用简明教程》之ExtJS的组件

Ext2.0对框架进行了非常大的重构,其中最重要的就是形成了一个结构及层次分明的组件体系,由这些组件形成了Ext的控件,Ext组件是由 Component类定义,每一种组件都有一个指定的xtype属性值,通过该值可以得到一个组件的类型或者是定义一个指定类型的组件。 ExtJS中的组件体系由下图所示:   组件大致可以分成三大类,即基本组件、工具栏组件、表单及元素组件。 基本组件有:

xtype            Class -------------    ------------------ box              Ext.BoxComponent  具有边框属性的组件 button           Ext.Button  按钮 colorpalette     Ext.ColorPalette 调色板 component        Ext.Component 组件 container        Ext.Container 容器 cycle            Ext.CycleButton  dataview         Ext.DataView 数据显示视图 datepicker       Ext.DatePicker 日期选择面板 editor           Ext.Editor 编辑器 editorgrid       Ext.grid.EditorGridPanel 可编辑的表格  grid             Ext.grid.GridPanel 表格 paging           Ext.PagingToolbar 工具栏中的间隔 panel            Ext.Panel 面板 progress         Ext.ProgressBar 进度条 splitbutton      Ext.SplitButton 可分裂的按钮 tabpanel         Ext.TabPanel 选项面板 treepanel        Ext.tree.TreePanel viewport         Ext.ViewPort 视图 window           Ext.Window 窗口

工具栏组件有 --------------------------------------- toolbar          Ext.Toolbar 工具栏 tbbutton         Ext.Toolbar.Button 按钮 tbfill           Ext.Toolbar.Fill 文件 tbitem           Ext.Toolbar.Item 工具条项目 tbseparator      Ext.Toolbar.Separator 工具栏分隔符 tbspacer         Ext.Toolbar.Spacer 工具栏空白 tbsplit          Ext.Toolbar.SplitButton 工具栏分隔按钮 tbtext           Ext.Toolbar.TextItem 工具栏文本项

表单及字段组件包含: --------------------------------------- form             Ext.FormPanel Form面板  checkbox         Ext.form.Checkbox checkbox录入框 combo            Ext.form.ComboBox combo选择项 datefield        Ext.form.DateField 日期选择项 field            Ext.form.Field 表单字段 fieldset         Ext.form.FieldSet 表单字段组 hidden           Ext.form.Hidden 表单隐藏域 htmleditor       Ext.form.HtmlEditor html编辑器 numberfield      Ext.form.NumberField 数字编辑器 radio            Ext.form.Radio 单选按钮 textarea         Ext.form.TextArea 区域文本框 textfield        Ext.form.TextField 表单文本框 timefield        Ext.form.TimeField 时间录入项 trigger          Ext.form.TriggerField 触发录入项

九、         ExtJS2.0实用简明教程》之Column列布局

Column列布局由Ext.layout.ColumnLayout类定义,名称为column。列布局把整个容器组件看成一列,然后往里面放入子元素的时候,可以通过在子元素中指定使用columnWidthwidth来指定子元素所占的列宽度。columnWidth表示使用百分比的形式指定列宽度,而width则是使用绝对象素的方式指定列宽度,在实际应用中可以混合使用两种方式。看下面的代码:

Ext.onReady(function(){
    
    

   
   
    
     
   
   
new Ext.Panel({
    
    

   
   
    
     
   
   
renderTo:"hello",
    
    

   
   
    
     
   
   
title:"容器组件",
     
     

   
   
    
     
   
   
layout:"column",
    
    

   
   
    
     
   
   
width:500,
    
    

   
   
    
     
   
   
height:100,
    
    

   
   
    
     
   
   
items:[{title:"1",width:100},
     
     

   
   
    
     
   
   
{title:"2",width:200},
     
     

   
   
    
     
   
   
{title:"3",width:100},
     
     

   
   
    
     
   
   
{title:"4"}
     
     

   
   
    
     
   
   
]
    
    

   
   
    
     
   
   
}
    
    

   
   
    
     
   
   
);
    
    

   
   
    
     
   
   
});
    
    

上面的代码在容器组件中放入了四个元素,在容器组件中形成4列,列的宽度分别为100,200,100及剩余宽度,执行结果如下图所示。

也可使用columnWidth来定义子元素所占的列宽度,看下面的代码:

Ext.onReady(function(){
    
    

   
   
    
     
   
   
new Ext.Panel({
    
    

   
   
    
     
   
   
renderTo:"hello",
    
    

   
   
    
     
   
   
title:"容器组件",
     
     

   
   
    
     
   
   
layout:"column",
    
    

   
   
    
     
   
   
width:500,
    
    

   
   
    
     
   
   
height:100,
    
    

   
   
    
     
   
   
items:[{title:"1",columnWidth:.2},
     
     

   
   
    
     
   
   
{title:"2",columnWidth:.3},
     
     

   
   
    
     
   
   
{title:"3",columnWidth:.3},
     
     

   
   
    
     
   
   
{title:"4",columnWidth:.2}
     
     

   
   
    
     
   
   
]
    
    

   
   
    
     
   
   
}
    
    

   
   
    
     
   
   
);
    
    

   
   
    
     
   
   
});
    
    

注意columnWidth的总和应该为1,执行代码将生成如下图所示的内容:

在实际应用中还可以混合使用,看下面的代码:

Ext.onReady(function(){
    
    

   
   
    
     
   
   
new Ext.Panel({
    
    

   
   
    
     
   
   
renderTo:"hello",
    
    

   
   
    
     
   
   
title:"容器组件",
     
     

   
   
    
     
   
   
layout:"column",
    
    

   
   
    
     
   
   
width:500,
    
    

   
   
    
     
   
   
height:100,
    
    

   
   
    
     
   
   
items:[{title:"1",width:200},
     
     

   
   
    
     
   
   
{title:"2",columnWidth:.3},
     
     

   
   
    
     
   
   
{title:"3",columnWidth:.3},
     
     

   
   
    
     
   
   
{title:"4",columnWidth:.4}
     
     

   
   
    
     
   
   
]
    
    

   
   
    
     
   
   
}
    
    

   
   
    
     
   
   
);
    
    

   
   
    
     
   
   
});
    
    

执行上面的代码将会生成如下图所示的结果:

十、         ExtJS2.0实用简明教程》之Column列布局

Column列布局由Ext.layout.ColumnLayout类定义,名称为column。列布局把整个容器组件看成一列,然后往里面放入子元素的时候,可以通过在子元素中指定使用columnWidthwidth来指定子元素所占的列宽度。columnWidth表示使用百分比的形式指定列宽度,而width则是使用绝对象素的方式指定列宽度,在实际应用中可以混合使用两种方式。看下面的代码:

Ext.onReady(function(){
    
    

   
   
    
     
   
   
new Ext.Panel({
    
    

   
   
    
     
   
   
renderTo:"hello",
    
    

   
   
    
     
   
   
title:"容器组件",
     
     

   
   
    
     
   
   
layout:"column",
    
    

   
   
    
     
   
   
width:500,
    
    

   
   
    
     
   
   
height:100,
    
    

   
   
    
     
   
   
items:[{title:"1",width:100},
     
     

   
   
    
     
   
   
{title:"2",width:200},
     
     

   
   
    
     
   
   
{title:"3",width:100},
     
     

   
   
    
     
   
   
{title:"4"}
     
     

   
   
    
     
   
   
]
    
    

   
   
    
     
   
   
}
    
    

   
   
    
     
   
   
);
    
    

   
   
    
     
   
   
});
    
    

上面的代码在容器组件中放入了四个元素,在容器组件中形成4列,列的宽度分别为100,200,100及剩余宽度,执行结果如下图所示。

也可使用columnWidth来定义子元素所占的列宽度,看下面的代码:

Ext.onReady(function(){
    
    

   
   
    
     
   
   
new Ext.Panel({
    
    

   
   
    
     
   
   
renderTo:"hello",
    
    

   
   
    
     
   
   
title:"容器组件",
     
     

   
   
    
     
   
   
layout:"column",
    
    

   
   
    
     
   
   
width:500,
    
    

   
   
    
     
   
   
height:100,
    
    

   
   
    
     
   
   
items:[{title:"1",columnWidth:.2},
     
     

   
   
    
     
   
   
{title:"2",columnWidth:.3},
     
     

   
   
    
     
   
   
{title:"3",columnWidth:.3},
     
     

   
   
    
     
   
   
{title:"4",columnWidth:.2}
     
     

   
   
    
     
   
   
]
    
    

   
   
    
     
   
   
}
    
    

   
   
    
     
   
   
);
    
    

   
   
    
     
   
   
});
    
    

注意columnWidth的总和应该为1,执行代码将生成如下图所示的内容:

在实际应用中还可以混合使用,看下面的代码:

Ext.onReady(function(){
    
    

   
   
    
     
   
   
new Ext.Panel({
    
    

   
   
    
     
   
   
renderTo:"hello",
    
    

   
   
    
     
   
   
title:"容器组件",
     
     

   
   
    
     
   
   
layout:"column",
    
    

   
   
    
     
   
   
width:500,
    
    

   
   
    
     
   
   
height:100,
    
    

   
   
    
     
   
   
items:[{title:"1",width:200},
     
     

   
   
    
     
   
   
{title:"2",columnWidth:.3},
     
     

   
   
    
     
   
   
{title:"3",columnWidth:.3},
     
     

   
   
    
     
   
   
{title:"4",columnWidth:.4}
     
     

   
   
    
     
   
   
]
    
    

   
   
    
     
   
   
}
    
    

   
   
    
     
   
   
);
    
    

   
   
    
     
   
   
});
    
    

执行上面的代码将会生成如下图所示的结果:

十一、              ExtJS2.0实用简明教程》之组件的使用

组件可以直接通过new 关键子来创建,比如控件一个窗口,使用new Ext.Window(),创建一个表格则使用new Ext.GridPanel()。当然,除了一些普通的组件以外,一般都会在构造函数中通过传递构造参数来创建组件。 组件的构造函数中一般都可以包含一个对象,这个对象包含创建组件所需要的配置属性及值,组件根据构造函数中的参数属性值来初始化组件。比如下面的例子:

<script>

         var obj={title:"hello",width:300,height:200,html:'<h1>Hello,easyjf open source</h1>'};

         var panel=new Ext.Panel(obj);

         panel.render("hello");

         </script>

<div id="hello">&nbsp;</div>
    
    

运行上面的代码可以实现如下图所示的结果:

可以省掉变量obj,直接写成如下的形式:

var panel=new Ext.Panel({title:"hello",width:300,height:200,html:'<h1>Hello,easyjf open source</h1>'});

panel.render("hello");
    
    

render方法后面的参数表示页面上的div元素id,也可以直接在参数中通过renderTo参数来省略手动谳用render方法,只需要在构造函数的参数中添加一个renderTo属性即可,如下:

new Ext.Panel({renderTo:"hello",title:"hello",width:300,height:200,html:'<h1>Hello,easyjf open source</h1>'});
    
    

对于容器中的子元素组件,都支持延迟加载的方式创建控件,此时可以直接通过在需要父组件的构造函数中,通过给属性items传递数组方式实现构造。如下面的代码:

var panel=new Ext.TabPanel({width:300,height:200,items:[

         {title:"面板1",height:30},{title:"面板2",height:30},{title:"面板3",height:30}]

});

panel.render("hello");
     
     

注意中括号中加粗部份的代码,这些代码定义了TabPanel这个容器控件中的子元素,这里包括三个面板。上面的代码与下面的代码等价:

var panel=new Ext.TabPanel({width:300,height:200,items:[new Ext.Panel(

         {title:"面板1",height:30}),new Ext.Panel({title:"面板2",height:30}),new Ext.Panel({title:"面板3",height:30})]

});

panel.render("hello");
     
     

前者不但省略掉了new Ext.Panel这个构造函数,最重要前者只有在初始化TabPanel的时候,才会创建子面板,而第二种方式则在程序一开始就会创建子面板。也就是说,前者实现的延迟加载。

十二、              ExtJS2.0实用简明教程》之Fit布局

Column列布局由Ext.layout.ColumnLayout类定义,名称为column。列布局把整个容器组件看成一列,然后往里面放入子元素的时候,可以通过在子元素中指定使用columnWidthwidth来指定子元素所占的列宽度。columnWidth表示使用百分比的形式指定列宽度,而width则是使用绝对象素的方式指定列宽度,在实际应用中可以混合使用两种方式。看下面的代码:

Ext.onReady(function(){
    
    
new Ext.Panel({
    
    
renderTo:"hello",
    
    
title:"容器组件",
     
     
layout:"column",
    
    
width:500,
    
    
height:100,
    
    
items:[{title:"1",width:100},
     
     
{title:"2",width:200},
     
     
{title:"3",width:100},
     
     
{title:"4"}
     
     
]
    
    
}
    
    
);
    
    
});
    
    

 

上面的代码在容器组件中放入了四个元素,在容器组件中形成4列,列的宽度分别为100,200,100及剩余宽度,执行结果如下图所示。

再看使用Fit布局后的代码,如下:

Ext.onReady(function(){
    
    

   
   
    
     
   
   
new Ext.Panel({
    
    

   
   
    
     
   
   
renderTo:"hello",
    
    

   
   
    
     
   
   
title:"容器组件",
     
     

   
   
    
     
   
   
layout:"fit",
    
    

   
   
    
     
   
   
width:500,
    
    

   
   
    
     
   
   
height:100,
    
    

   
   
    
     
   
   
items:[{title:"子元素",html:"这是子元素中的内容"}
     
     

   
   
    
     
   
   
]
    
    

   
   
    
     
   
   
}
    
    

   
   
    
     
   
   
);
    
    

   
   
    
     
   
   
});
    
    

上面的代码指定父容器使用Fit布局,因此子将自动填满整个父容器。输出的图形如下:

如果容器组件中有多个子元素,则只会显示一个元素,如下面的代码:

 

Ext.onReady(function(){
    
    

   
   
    
     
   
   
new Ext.Panel({
    
    

   
   
    
     
   
   
renderTo:"hello",
    
    

   
   
    
     
   
   
title:"容器组件",
     
     

   
   
    
     
   
   
layout:"fit",
    
    

   
   
    
     
   
   
width:500,
    
    

   
   
    
     
   
   
height:100,
    
    

   
   
    
     
   
   
items:[{title:"子元素1",html:"这是子元素1中的内容"},
     
     

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

   
   
    
     
   
   
]
    
    

   
   
    
     
   
   
}
    
    

   
   
    
     
   
   
);
    
    

   
   
    
     
   
   
});
    
    

输出的结果如下:

如果不使用布局Fit,代码如下:

Ext.onReady(function(){
    
    

   
   
    
     
   
   
new Ext.Panel({
    
    

   
   
    
     
   
   
renderTo:"hello",
    
    

   
   
    
     
   
   
title:"容器组件",
     
     

   
   
    
     
   
   
width:500,
    
    

   
   
    
     
   
   
height:120,
    
    

   
   
    
     
   
   
items:[{title:"子元素1",html:"这是子元素1中的内容"},
     
     

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

   
   
    
     
   
   
]
    
    

   
   
    
     
   
   
}
    
    

   
   
    
     
   
   
);
    
    

   
   
    
     
   
   
});
    
    

输出的结果如下图所示:

十三、              ExtJS2.0实用简明教程》之Form布局

Form布局由类Ext.layout.FormLayout定义,名称为form,是一种专门用于管理表单中输入字段的布局,这种布局主要用于在程序中创建表单字段或表单元素等使用。看下面的代码:

Ext.onReady(function(){
    
    

   
   
    
     
   
   
new Ext.Panel({
    
    

   
   
    
     
   
   
renderTo:"hello",
    
    

   
   
    
     
   
   
title:"容器组件",
     
     

   
   
    
     
   
   
width:300,
    
    

   
   
    
     
   
   
layout:"form",
    
    

   
   
    
     
   
   
hideLabels:false,
    
    

   
   
    
     
   
   
labelAlign:"right",
    
    

   
   
    
     
   
   
height:120,
    
    

   
   
    
     
   
   
defaultType: 'textfield',
    
    

   
   
    
     
   
   
items:[
    
    

   
   
    
     
   
   
{fieldLabel:"请输入姓名",name:"name"},
     
     

   
   
    
     
   
   
{fieldLabel:"请输入地址",name:"address"},
     
     

   
   
    
     
   
   
{fieldLabel:"请输入电话",name:"tel"}
     
     

   
   
    
     
   
   
]
    
    

   
   
    
     
   
   
}
    
    

   
   
    
     
   
   
);
    
    

   
   
    
     
   
   
});
    
    

上面的代码创建了一个面板,面板使用Form布局,面板中包含三个子元素,这些子元素都是文本框字段,在父容器中还通过hideLabelslabelAlign等配置属性来定义了是否隐藏标签、标签对齐方式等。上面代码的输出结果如下图所示:

可以在容器组件中把hideLabels设置为true,这样将不会显示容器中字段的标签了,如下图所示:

在实际应用中,Ext.form.FormPanel这个类默认布局使用的是Form布局,而且FormPanel还会创建与 <form> 标签相关的组件,因此一般情况下我们直接使用FormPanel即可。上面的例子可改写成如下的形式:

Ext.onReady(function(){
    
    

   
   
    
     
   
   
new Ext.form.FormPanel({
    
    

   
   
    
     
   
   
renderTo:"hello",
    
    

   
   
    
     
   
   
title:"容器组件",
     
     

   
   
    
     
   
   
width:300,
    
    

   
   
    
     
   
   
labelAlign:"right",
    
    

   
   
    
     
   
   
height:120,
    
    

   
   
    
     
   
   
defaultType: 'textfield',
    
    

   
   
    
     
   
   
items:[
    
    

   
   
    
     
   
   
{fieldLabel:"请输入姓名",name:"name"},
     
     

   
   
    
     
   
   
{fieldLabel:"请输入地址",name:"address"},
     
     

   
   
    
     
   
   
{fieldLabel:"请输入电话",name:"tel"}
     
     

   
   
    
     
   
   
]
    
    

   
   
    
     
   
   
}
    
    

   
   
    
     
   
   
);
    
    

   
   
    
     
   
   
});
    
    

程序结果与前面使用Ext.Panel并指定form布局的一样,如下图所示:

十四、              ExtJS2.0实用简明教程》之组件的配置属性

ExtJS中,除了一些特殊的组件或类以外,所有的组件在初始化的时候都可以在构造函数使用一个包含属性名称及值的对象,该对象中的信息也就是指组件的配置属性。 比如配置一个面板:

new Ext.Panel({          title:"面板",          html"面板内容",          height:100});

再比如创建一个按钮:

var b=new Ext.Button({          text:"添加",          pressed:true,          heigth:30,          handler:Ext.emptyFn          });

再比如创建一个Viewport及其中的内容:

new Ext.Viewport({          layout:"border",          items:[          {          region:"north",          title:"面板",          html:"面板内容",          height:100},          {          region:"center",          xtype:"grid",                title:"学生信息管理",          store:troe,          cm:colM,          store:store,          autoExpandColumn:3          }          ] });

每一个组件除了继承基类中的配置属性以外,还会根据需要增加自己的配置属性,另外子类中有的时候还会把父类的一些配置属性的含义及用途重新定 义。学习及使用ExtJS,其中最关键的是掌握ExtJS中的各个组件的配置属性及具体的含义,这些配置属性在下载下来的ExtJS源码文档中都有详细的 说明,可以通过这个文档详细了解每一个组件的特性,如下图所示:

由于所有的组件都继承自Ext.Component,因此在这里我们列出组件基类Component中的配置属性简单介绍。

配置属性名称

类型

简介

allowDomMove

Boolean

当渲染这个组件时是否允许移动Dom节点(默认值为true)。

applyTo

Mixed

合参数,表示把该组件应用指定的对象。参数可以是节点的id,一个DOM节点或一个存在的元素或与之相对应的在document中已出现的id。当使用 applyTo,也可以提供一个idCSSclass名称,如果子组件允许它将尝试创建一个。如果指写applyTo选项,所有传递到 renderTo方法的值将被忽略,并且目标元素的父节点将自动指定为这个组件的容器。使用applyTo选项后,则不需要再调用render()方法来 渲染组件。

autoShow

Boolean

自动显示,如为true,则组件将检查所有隐藏类型的class(如:’x-hidden’ ’x-hide-display’并在渲染时移除(默认为false)

cls

String

给组件添加额外的样式信息,(默认值为''),如果想自定义组件或它的子组件的样式,这个选项是非常有用的。

ctCls

String

给组件的容器添加额外的样式信息,默认值为'')

disabledClass

String

给被禁用的组件添加额外的CSS样式信息,(默认为"x-item-disabled")。

hideMode

String

组件的隐藏方式,支持的值有’visibility’,也就是css里的visibility’offsets’负数偏移位置的值和’display’也就是css里的display,默认值为’display’

hideParent

Boolean

是否隐藏父容器,该值为true时将会显示或隐藏组件的容器,false时则只隐藏和显示组件本身(默认值为false)。

id

String

组件的id,默认为一个自动分配置的id

listeners

Object

给对象配置多个事件监听器,在对象初始化会初始化这些监听器。

plugins

Object/Array

个对象或数组,将用于增加组件的自定义功能。一个有效的组件插件必须包含一个init方法,该方法可以带一个Ext.Component类型参数。当组件 建立后,如果该组件包含有效的插件,将调用每一个插件的init方法,把组件传递给插件,插件就能够实现对组件的方法调用及事件应用等,从而实现对组件功 能的扩充。

renderTo

Mixed

混合数据参数,指定要渲染到节点的id,一个DOM的节点或一个已存在的容器。如果使用了这个配置选项,则组件的render()就不是必需的了。

stateEvents

Array

定义需要保存组件状态信息的事件。当指定的事件发生时,组件会保存它的状态(默认为none),其值为这个组件支持的任意event类型,包含组件自身的或自定义事件。(例如:[‘click’,’customerchange’])。

stateId

String

组件的状态ID,状态管理器使用该id来管理组件的状态信息,默认值为组件的id

style

String

给该组件的元素指定特定的样式信息,有效的参数为Ext.Element.applyStyles中的值。

xtype

String

指定所要创建组件的xtype,用于构造函数中没有意义。该参数用于在容器组件中创建创建子组件并延迟实例化和渲染时使用。如果是自定义的组件,则需要用Ext.ComponentMgr.registerType来进行注册,才会支持延迟实例化和渲染。

el

Mixed

相当于applyTo

十五、              ExtJS2.0实用简明教程》之Accordion布局

Accordion布局由类Ext.layout.Accordion定义,名称为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中的内容"}
     
     

   
   
    
     
   
   
]
    
    

   
   
    
     
   
   
}
    
    

   
   
    
     
   
   
);
    
    

   
   
    
     
   
   
});
    
    

上面的代码定义了一个容器组件,指定使用Accordion布局,该容器组件中包含三个子元素,在layoutConfig中指定布局配置参数animatetrue,表示在执行展开折叠时是否应用动画效果。执行结果将生成如下图所示的界面:

点击每一个子元素的头部名称或右边的按钮,则会展开该面板,并收缩其它已经展开的面板,如下图:

十六、              ExtJS2.0实用简明教程》之事件处理

ExtJS提供了一套强大的事件处理机制,通过这些事件处理机制来响应用户的动作、监控控件状 态变化、更新控件视图信息、与服务器进行交互等等。事件统一由Ext.EventManager对象管理,与浏览器W 3C 标准事件对象Event相对 应,Ext封装了一个Ext.EventObject事件对象。支持事件处理的类(或接口)Ext.util.Observable,凡是继承该类的组 件或类都支持往对象中添加事件处理及响应功能。 首先我们来看标准html中的事件处理,看下面的html代码:

<script>

         function a()

         {

                   alert('some thing');

         }

</script>

<input id="btnAlert" type="button" οnclick="a();" value="alert" />
     
     

点击这个按钮则会触发onclick事件,并执行onclick事件处理函数中指定的代码,这里直接执行函数a中的代码,也即弹出一个简单的信息提示框。再简单修改一下上面的代码,内容如下:

<script>

function a()

{

alert('some thing');

}

window.οnlοad=function()

{

document.getElementById("btnAlert").οnclick=a;

}

</script>

<input id="btnAlert" type="button" value="alert" />
     
     

上面的代码在文档加载的时候,就直接对btnAlertonclick赋值,非常清晰的指明了按钮btnAlertonclick事件响应函数为a,注意这里a后面不能使用括号“()” ExtJS中组件的事件处理跟上面相似,看下面的代码:

<script>

function a()

{

alert('some thing');

}



Ext.onReady(function(){      

Ext.get("btnAlert").addListener("click",a);

          });

</script>

<input id="btnAlert" type="button" value="alert" />
     
     

Ext.get("btnAlert")得到一个与页面中按钮btnAlert关联的Ext.Element对象,可以直接调用该对象上的 addListener方法来给对象添加事件,同样实现前面的效果。在调用addListener 方法的代码中,第一个参数表示事件名称,第二个参数表示事件处理器或整个响应函数。 ExtJS支持事件队列,可以往对象的某一个事件中添加多个事件响应函数,看下面的代码:

Ext.onReady(function(){      

Ext.get("btnAlert").on("click",a);

Ext.get("btnAlert").on("click",a);

 });
    
    

addLinster方法的另外一个简写形式是on,由于调用了两次addListener方法,因此当点击按钮的时候会弹出两次信息。 当然,ExtJS还支持事件延迟处理或事件处理缓存等功能,比如下面的代码:

Ext.onReady(function(){      

         Ext.get("btnAlert").on("click",a,this,{delay:2000});

 });
    
    

由于在调用addListener的时候传递指定的delay2000,因此当用户点击按钮的时候,不会马上执行事件响应函数,而是在2000毫秒,也就是两秒后才会弹出提示信息框。   当然,在使用Ext的事件时,我们一般是直接在控件上事件,每一个控件包含哪些事件,在什么时候触发,触发时传递的参数等,在ExtJS项目的文档中 都有较为详细的说明。比如对于所有的组件Component,都包含一个beforedestroy事件,该事件会在Ext销毁这一个组件时触发,如果事 件响应函数返回false,则会取消组件的销毁操作。

Ext.onReady(function(){      

         var win=new Ext.Window({

         title:"不能关闭的窗口",

         height:200,

         width:300 

         });

         win.on("beforedestroy",function(obj){

                   alert("想关闭我,这是不可能的!");

                   obj.show();

                   return false;

         });

         win.show();

});
     
     

由于在窗口对象的beforedestroy事件响应函数返回值为false,因此执行这段程序,你会发现这个窗口将无法关闭。组件的事件监听器可以直接在组件的配置属性中直接声明,如下面的代码与前面实现的功能一样:

Ext.onReady(function(){      

         var win=new Ext.Window({

         title:"不能关闭的窗口",

         height:200,

         width:300,

         listeners:{"beforedestroy":function(obj){

                   alert("想关闭我,这是不可能的!");

                   obj.show();

                   return false;

         }}        

         });       

         win.show();

});
     
     

了解了ExtJS中的基本事件处理及使用方法,就可以在你的应用中随心所欲的进行事件相关处理操作了。 关于ExtJS中事件处理中作用域、事件处理原理、给自定义的组件添加事件、处理相关的Ext.util.ObservableExt.EventManager类详细介绍,请参考wlr.easyjf.com中的VIP文档《ExtJS中的事件处理详解》。

十七、              ExtJS2.0实用简明教程》之Card布局

Card布局由Ext.layout.CardLayout类定义,名称为card,该布局将会在容器组件中某一时刻使得只显示一个子元素。可以满足安装向导、Tab选项板等应用中面板显示的需求。看下面的代码:

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;
    
    

   
   
    
     
   
   
}
    
    

   
   
    
     
   
   
});
    
    

上面的代码创建了一个容器组件面板,面板中包含三个子面板元素,父容器包含一个切换按钮,点击该按钮将会执行changeTab函数,该函数实现把父容器中的活动面板在三个子元素之间进行切换。程序的执行结果如下所示:

点击一下切换按钮,结果如下图所示:

十八、              ExtJS2.0实用简明教程》之able布局及其它布局

Table布局由类Ext.layout.TableLayout定义,名称为table,该布局负责把容器中的子元素按照类似普通html标签

 

 

 

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中的内容"}

 

]

 

}

 

);

 

});

上面的代码创建了一个父容器组件,指定使用Table布局,layoutConfig使用columns指定父容器分成3列,子元素中使用rowspancolspan来指定子元素所横跨的单元格数。程序的运行效果如下图所示:

除了前面介绍的几种布局以外,Ext2.0中还包含其它的Ext.layout.AbsoluteLayoutExt.layout.AnchorLayout等布局类,这些布局主要作为其它布局的基类使用,一般情况下我们不会在应用中直接使用。另外,我们也可以继承10种布局类的一种,来实现自定义的布局。

十九、              ExtJS2.0实用简明教程》之Panel

面板PanelExtJS控件的基础,很高级控件都是在面板的基础上扩展的,还有其它大多数控件也都直接或间接有关系。应用程序的界面一般情况下是由一个一个的面板通过不同组织方式形成。 面板由以下几个部分组成,一个顶部工具栏、一个底部工具栏、面板头部、面板尾部、面板主区域几个部分组件。面板类中还内置了面板展开、关闭等功能,并 提供一系列可重用的工具按钮使得我们可以轻松实现自定义的行为,面板可以放入其它任何容器中,面板本身是一个容器,他里面又可以包含各种其它组件。 面板的类名为Ext.Panel,其xtypepanel,下面的代码可以显示出面板的各个组成部分:

Ext.onReady(function(){

         new Ext.Panel({

                   renderTo:"hello",

                   title:"面板头部header",

                   width:300,

                   height:200,

                   html:'<h1>面板主区域</h1>',

                   tbar:[{text:'顶部工具栏topToolbar'}],

                   bbar:[{text:'底部工具栏bottomToolbar'}],

                   buttons:[{text:"按钮位于footer"}]

                   });

 });
     
     

运行该代码,可以得到如图xx所示的输出结果,清楚的表示出了面板的各个组成部分。

一般情况下,顶部工具栏或底部工具栏只需要一个,而面板中一般也很少直接包含按钮,一般会把面板上的按钮直接放到工具栏上面。比如下面的代码:

Ext.onReady(function(){

         new Ext.Panel({

                   renderTo:"hello",

                   title:"hello",

                   width:300,

                   height:200,

                   html:'<h1>Hello,easyjf open source!</h1>',

                   tbar:[{pressed:true,text:'刷新'}]                            

                   });

 });
     
     

可以得到如图xx所示的效果,该面板包含面板Header,一个顶部工具栏及面板区域三个部分。

二十、              ExtJS2.0实用简明教程》之工具栏Toolbar

面板中可以有工具栏,工具栏可以位于面板顶部或底部,Ext中工具栏是由Ext.Toolbar类表示。工具栏上可以存放按钮、文本、分隔符等内容。面板对象中内置了很多实用的工具栏,可以直接通过面板的tools配置选项往面板头部加入预定义的工具栏选项。 比如下面的代码:

Ext.onReady(function(){

         new Ext.Panel({

                   renderTo:"hello",

                   title:"hello",

                   width:300,

                   height:200,

                   html:'<h1>Hello,easyjf open source!</h1>',

                   tools:[{

                             id:"save"},

                             {id:"help",

                                       handler:function(){Ext.Msg.alert('help','please help me!');}

                             },

                             {id:"close"}],

                   tbar:[{pressed:true,text:'刷新'}]                            

                   });

 });
     
     

注意我们在Panel的构造函数中设置了tools属性的值,表示在面板头部显示三个工具栏选项按钮,分别是保存"save""help""close"三种。代码运行的效果图如下:

点击 help按钮会执行handler中的函数,显示一个弹出对话框,而点击其它的按钮不会有任何行为产生,因为没有定义他们的heanlder

除了在面板头部加入这些已经定义好的工具栏选择按钮以外,还可以在顶部或底工具栏中加入各种工具栏选项。这些工具栏选项主要包括按钮、文本、空白、填充条、分隔符等。代码:

Ext.onReady(function(){

         new Ext.Panel({

                   renderTo:"hello",

                   title:"hello",

                   width:300,

                   height:200,

                   html:'<h1>Hello,easyjf open source!</h1>',                   

                   tbar:[new Ext.Toolbar.TextItem('工具栏:'),

                             {xtype:"tbfill"},

                             {pressed:true,text:'添加'},

                             {xtype:"tbseparator"},

                             {pressed:true,text:'保存'} 

                             ]                              

                   });

          });
     
     

将会得到如图xx所示的结果:

Ext中的工具栏项目主要包含下面的类: Ext.Toolbar.Button-按钮,xtypetbbutton TextItem Ext.Toolbar.Fill Separator Spacer SplitButton

二十一、    ExtJS2.0实用简明教程》之选项面板TabPanel

在前面的示例中,为了显示一个面板,我们需要在页面上添加一个,然后把 Ext控件渲染到这个div上。VeiwPort代表整个浏览器显示区域,该对象渲染到页面的body区域,并会随着浏览器显示区域的大小自动改变,一个 页面中只能有一个ViewPort实例。看下面的代码:

Ext.onReady(function(){

         new Ext.Viewport({             

                   enableTabScroll:true,

                   layout:"fit",

                   items:[{title:"面板",

                                 html:"",

                                 bbar:[{text:"按钮1"},

                                       {text:"按钮2"}]

                                 }]              

                   });

 });
     
     

运行上面的代码会得到如图xxx所示的输出结果。

Viewport不需要再指定renderTo,而我们也看到Viewport确实填充了整个浏览器显示区域,并会随着浏览器显示区域大小的改变而改改。 Viewport主要用于应用程序的主界面,可以通过使用不同的布局来搭建出不同风格的应用程序主界面。在Viewport上常用的布局有fitborder等,当然在需要的时候其它布局也会常用。看下面的代码:

Ext.onReady(function(){

         new Ext.Viewport({             

                   enableTabScroll:true,

                   layout:"border",

                   items:[{title:"面板",

                                 region:"north",

                                 height:50,

                                 html:"<h1>网站后台管理系统!</h1>"

                                 },

                                 {title:"菜单",

                                 region:"west",

                                 width:200,

                                 collapsible:true, 

                                 html:"菜单栏"

                                 },

                                 {

                                 xtype:"tabpanel",                                 

                                 region:"center",

                                 items:[{title:"面板1"},

                                          {title:"面板2"}]                        

                                 }

                                 ]               

                   });

          });
     
     

运行上面的程序会得如图xx所示的效果。

二十二、    ExtJS2.0实用简明教程》之基本表格GridPanel

ExtJS中的表格功能非常强大,包括了排序、缓存、拖动、隐藏某一列、自动显示行号、列汇总、单元格编辑等实用功能。         表格由类Ext.grid.GridPanel定义,继承自Panel,其xtypegridExtJS中,表格Grid必须包含列定义信息,并指定表格的数据存储器Store。表格的列信息由类Ext.grid.ColumnModel定义、而表格的数据存储器由Ext.data.Store定义,数据存储器根据解析的数据不同分为JsonStoreSimpleStroeGroupingStore等。         我们首先来看最简单的使用表格的代码:

Ext.onReady(function(){
    
    

   
   
    
     
   
   
var data=[ [1, 'EasyJWeb', 'EasyJF','www.easyjf.com'],
    
    

   
   
    
     
   
   
[2, 'jfox', 'huihoo','www.huihoo.org'],
    
    

   
   
    
     
   
   
[3, 'jdon', 'jdon','www.jdon.com'],
    
    

   
   
    
     
   
   
[4, 'springside', 'springside','www.springside.org.cn'] ];
    
    

   
   
    
     
   
   
var store=new Ext.data.SimpleStore({data:data,fields:["id","name","organization","homepage"]});
    
    

   
   
    
     
   
   
var grid = new Ext.grid.GridPanel({
    
    

   
   
    
     
   
   
renderTo:"hello",
    
    

   
   
    
     
   
   
title:"中国Java开源产品及团队",
     
     

   
   
    
     
   
   
height:150,
    
    

   
   
    
     
   
   
width:600,
    
    

   
   
    
     
   
   
columns:[{header:"项目名称",dataIndex:"name"},
     
     

   
   
    
     
   
   
{header:"开发团队",dataIndex:"organization"},
     
     

   
   
    
     
   
   
{header:"网址",dataIndex:"homepage"}],
     
     

   
   
    
     
   
   
store:store,
    
    

   
   
    
     
   
   
autoExpandColumn:2
    
    

   
   
    
     
   
   
});
    
    

   
   
    
     
   
   
});
    
    

执行上面的代码,可以得到一个简单的表格,如下图所示:

上面的代码中,第一行“var data=…”用来定义表格中要显示的数据,这是一个[][]二维数组;第二行“var store=…”用来创建一个数据存储,这是GridPanel需要使用配置属性,数据存储器Store负责把各种各样的数据(如二维数组、JSon对象数组、xml文本)等转换成ExtJS的数据记录集Record,关于数据存储器Store我们将在下一章中作专门介绍。第三行“var grid = new Ext.grid.GridPanel(…)”负责创建一个表格,表格包含的列由columns配置属性来描述,columns是一数组,每一行数据元素描述表格的一列信息,表格的列信息包含列头显示文本(header)、列对应的记录集字段(dataIndex)、列是否可排序(sorable)、列的渲染函数(renderer)、宽度(width)、格式化信息(format)等,在上面的列子中只用到了headerdataIndex         下面我们看简单看看表格的排序及隐藏列特性,简单修改一下上面的代码,内容如下:

Ext.onReady(function(){
    
    

   
   
    
     
   
   
var data=[ [1, 'EasyJWeb', 'EasyJF','www.easyjf.com'],
    
    

   
   
    
     
   
   
[2, 'jfox', 'huihoo','www.huihoo.org'],
    
    

   
   
    
     
   
   
[3, 'jdon', 'jdon','www.jdon.com'],
    
    

   
   
    
     
   
   
[4, 'springside', 'springside','www.springside.org.cn'] ];
    
    

   
   
    
     
   
   
var store=new Ext.data.SimpleStore({data:data,fields:["id","name","organization","homepage"]});
    
    

   
   
    
     
   
   
var colM=new Ext.grid.ColumnModel([{header:"项目名称",dataIndex:"name",sortable:true},
     
     

   
   
    
     
   
   
{header:"开发团队",dataIndex:"organization",sortable:true},
     
     

   
   
    
     
   
   
{header:"网址",dataIndex:"homepage"}]);
     
     

   
   
    
     
   
   
var grid = new Ext.grid.GridPanel({
    
    

   
   
    
     
   
   
renderTo:"hello",
    
    

   
   
    
     
   
   
title:"中国Java开源产品及团队",
     
     

   
   
    
     
   
   
height:200,
    
    

   
   
    
     
   
   
width:600,
    
    

   
   
    
     
   
   
cm:colM,
    
    

   
   
    
     
   
   
store:store,
    
    

   
   
    
     
   
   
autoExpandColumn:2
    
    

   
   
    
     
   
   
});
    
    

   
   
    
     
   
   
});
    
    

直接使用new Ext.grid.ColumnModel来创建表格的列信定义信息,在项目名称开发团队列中我们添加了sortabletrue的属性,表示该列可以排序,执行上面的代码,我们可以得到一个支持按项目名称开发团队的表格,如图xxx所示。

(按项目名称排序)

(可排序的列表头后面小按钮可以弹出操作菜单)

(可以指定隐藏哪些列)

另外,每一列的数据渲染方式还可以自己定义,比如上面的表格中,我们希望用户在表格中点击网址则直接打开这些开源团队的网站,也就是需要给网址这一列添加上超级连接。下面的代码实现这个功能:

function showUrl(value)
    
    

   
   
    
     
   
   
{
    
    

   
   
    
     
   
   
return ""+value+"";
    
    

   
   
    
     
   
   
}
    
    

   
   
    
     
   
   
Ext.onReady(function(){
    
    

   
   
    
     
   
   
var data=[ [1, 'EasyJWeb', 'EasyJF','www.easyjf.com'],
    
    

   
   
    
     
   
   
[2, 'jfox', 'huihoo','www.huihoo.org'],
    
    

   
   
    
     
   
   
[3, 'jdon', 'jdon','www.jdon.com'],
    
    

   
   
    
     
   
   
[4, 'springside', 'springside','www.springside.org.cn'] ];
    
    

   
   
    
     
   
   
var store=new Ext.data.SimpleStore({data:data,fields:["id","name","organization","homepage"]});
    
    

   
   
    
     
   
   
var colM=new Ext.grid.ColumnModel([{header:"项目名称",dataIndex:"name",sortable:true},
     
     

   
   
    
     
   
   
{header:"开发团队",dataIndex:"organization",sortable:true},
     
     

   
   
    
     
   
   
{header:"网址",dataIndex:"homepage",renderer:showUrl}]);
     
     

   
   
    
     
   
   
var grid = new Ext.grid.GridPanel({
    
    

   
   
    
     
   
   
renderTo:"hello",
    
    

   
   
    
     
   
   
title:"中国Java开源产品及团队",
     
     

   
   
    
     
   
   
height:200,
    
    

   
   
    
     
   
   
width:600,
    
    

   
   
    
     
   
   
cm:colM,
    
    

   
   
    
     
   
   
store:store,
    
    

   
   
    
     
   
   
autoExpandColumn:2
    
    

   
   
    
     
   
   
});
    
    

   
   
    
     
   
   
});
    
    

上面的代码跟前面的示例差别不大,只是在定义网址列的时候多了一个renderer属性,即{header:"网址",dataIndex:"homepage",renderer:showUrl}showUrl是一个自定义的函数,内容就是根据传入的value参数返回一个包含<a>标签的html片段。运行上面的代码显示结果如下图所示:

 

自定义的列渲染函数可以实现在单元格中显示自己所需要的各种信息,只是的浏览器能处理的html都可以。          除了二级数组以外,表格还能显示其它格式的数据吗?答案是肯定的,下面假如我们的表格数据data定义成了下面的形式:

var data=[{id:1,
    
    

   
   
    
     
   
   
name:'EasyJWeb',
    
    

   
   
    
     
   
   
organization:'EasyJF',
    
    

   
   
    
     
   
   
homepage:'www.easyjf.com'},
    
    

   
   
    
     
   
   
{id:2,
    
    

   
   
    
     
   
   
name:'jfox',
    
    

   
   
    
     
   
   
organization:'huihoo',
    
    

   
   
    
     
   
   
homepage:'www.huihoo.org'},
    
    

   
   
    
     
   
   
{id:3,
    
    

   
   
    
     
   
   
name:'jdon',
    
    

   
   
    
     
   
   
organization:'jdon',
    
    

   
   
    
     
   
   
homepage:'www.jdon.com'},
    
    

   
   
    
     
   
   
{id:4,
    
    

   
   
    
     
   
   
name:'springside',
    
    

   
   
    
     
   
   
organization: 'springside',
    
    

   
   
    
     
   
   
homepage:'www.springside.org.cn'}
    
    

   
   
    
     
   
   
];
    
    

也就是说数据变成了一维数组,数组中的每一个元素是一个对象,这些对象包含nameorganizationhomepageid等属性。要让表格显示上面的数据,其实非常简单,只需要把store改成用Ext.data.JsonStore即可,代码如下:

var store=new Ext.data.JsonStore({data:data,fields:["id","name","organization","homepage"]});
    
    

   
   
    
     
   
   
var colM=new Ext.grid.ColumnModel([{header:"项目名称",dataIndex:"name",sortable:true},
     
     

   
   
    
     
   
   
{header:"开发团队",dataIndex:"organization",sortable:true},
     
     

   
   
    
     
   
   
{header:"网址",dataIndex:"homepage",renderer:showUrl}]);
     
     

   
   
    
     
   
   
var grid = new Ext.grid.GridPanel({
    
    

   
   
    
     
   
   
renderTo:"hello",
    
    

   
   
    
     
   
   
title:"中国Java开源产品及团队",
     
     

   
   
    
     
   
   
height:200,
    
    

   
   
    
     
   
   
width:600,
    
    

   
   
    
     
   
   
cm:colM,
    
    

   
   
    
     
   
   
store:store,
    
    

   
   
    
     
   
   
autoExpandColumn:2
    
    

   
   
    
     
   
   
});
    
    

上面的代码得到的结果与前面的一样。当然,表格同样能显示xml格式的数据,假如上面的数据存放成hello.xml文件中,内容如下:

<?xml version="1.0" encoding="UTF-8"?>

<dataset>

 <row>

  <id>1</id>

  <name>EasyJWeb</name>

  <organization>EasyJF</organization>

  <homepage>www.easyjf.com</homepage>

 </row>

 <row>

  <id>2</id>

  <name>jfox</name>

  <organization>huihoo</organization>

  <homepage>www.huihoo.org</homepage>

 </row>

 <row>

  <id>3</id>

  <name>jdon</name>

  <organization>jdon</organization>

  <homepage>www.jdon.com</homepage>

 </row>

 <row>

  <id>4</id>

  <name>springside</name>

  <organization>springside</organization>

  <homepage>www.springside.org.cn</homepage>

 </row>

 </dataset>
    
    

为了把这个xml数据用ExtJS的表格Grid进行显示,我们只需要把store部分的内容调整成如下的内容即可:

var store=new Ext.data.Store({
    
    

   
   
    
     
   
   
url:"hello.xml",
    
    

   
   
    
     
   
   
reader:new Ext.data.XmlReader({
    
    

   
   
    
     
   
   
record:"row"},
    
    

   
   
    
     
   
   
["id","name","organization","homepage"])
    
    

   
   
    
     
   
   
});
    
    

其它的部分不用改变,完整的代码如下:

function showUrl(value)
    
    

   
   
    
     
   
   
{
    
    

   
   
    
     
   
   
return "<a href='http://"+value+"' target='_blank'>"+value+"</a>";
    
    

   
   
    
     
   
   
}
    
    

   
   
    
     
   
   
Ext.onReady(function(){
    
    

   
   
    
     
   
   
var store=new Ext.data.Store({
    
    

   
   
    
     
   
   
url:"hello.xml",
    
    

   
   
    
     
   
   
reader:new Ext.data.XmlReader({
    
    

   
   
    
     
   
   
record:"row"},
    
    

   
   
    
     
   
   
["id","name","organization","homepage"])
    
    

   
   
    
     
   
   
});
    
    

   
   
    
     
   
   
var colM=new Ext.grid.ColumnModel([{header:"项目名称",dataIndex:"name",sortable:true},
     
     

   
   
    
     
   
   
{header:"开发团队",dataIndex:"organization",sortable:true},
     
     

   
   
    
     
   
   
{header:"网址",dataIndex:"homepage",renderer:showUrl}]);
     
     

   
   
    
     
   
   
var grid = new Ext.grid.GridPanel({
    
    

   
   
    
     
   
   
renderTo:"hello",
    
    

   
   
    
     
   
   
title:"中国Java开源产品及团队",
     
     

   
   
    
     
   
   
height:200,
    
    

   
   
    
     
   
   
width:600,
    
    

   
   
    
     
   
   
cm:colM,
    
    

   
   
    
     
   
   
store:store,
    
    

   
   
    
     
   
   
autoExpandColumn:2
    
    

   
   
    
     
   
   
});
    
    

   
   
    
     
   
   
store.load();
    
    

   
   
    
     
   
   
});
    
    

store.laod()是用来加载数据,执行上面的代码产生的表格与前面的完全一样。

二十三、    ExtJS2.0实用简明教程》之视图区ViewPort

在前面的示例中,为了显示一个面板,我们需要在页面上添加一个div,然后把 Ext控件渲染到这个div上。VeiwPort代表整个浏览器显示区域,该对象渲染到页面的body区域,并会随着浏览器显示区域的大小自动改变,一个 页面中只能有一个ViewPort实例。看下面的代码:

Ext.onReady(function(){

         new Ext.Viewport({             

                   enableTabScroll:true,

                   layout:"fit",

                   items:[{title:"面板",

                                 html:"",

                                 bbar:[{text:"按钮1"},

                                       {text:"按钮2"}]

                                 }]              

                   });

 });
     
     

运行上面的代码会得到如图xxx所示的输出结果。

Viewport不需要再指定renderTo,而我们也看到Viewport确实填充了整个浏览器显示区域,并会随着浏览器显示区域大小的改变而改改。 Viewport主要用于应用程序的主界面,可以通过使用不同的布局来搭建出不同风格的应用程序主界面。在Viewport上常用的布局有fitborder等,当然在需要的时候其它布局也会常用。看下面的代码:

Ext.onReady(function(){

         new Ext.Viewport({             

                   enableTabScroll:true,

                   layout:"border",

                   items:[{title:"面板",

                                 region:"north",

                                 height:50,

                                 html:"<h1>网站后台管理系统!</h1>"

                                 },

                                 {title:"菜单",

                                 region:"west",

                                 width:200,

                                 collapsible:true, 

                                 html:"菜单栏"

                                 },

                                 {

                                 xtype:"tabpanel",                                 

                                 region:"center",

                                 items:[{title:"面板1"},

                                          {title:"面板2"}]                        

                                 }

                                 ]               

                   });

          });
     
     

运行上面的程序会得如图xx所示的效果。

二十四、    ExtJS2.0实用简明教程》之可编辑表格EditorGridPanel

可编辑表格是指可以直接在表格的单元格对表格的数据进行编辑,ExtJS中的可编辑表格由类Ext.grid.EditorGridPanel表示,xtypeeditorgrid。使用EditorGridPanel与使用普通的GridPanel方式一样,区别只是在定义列信息的时候,可以指定某一列使用的编辑即可,下面来看一个简单的示例。

Ext.onReady(function(){
    
    

   
   
    
     
   
   
var data=[{id:1,
    
    

   
   
    
     
   
   
name:'小王',
     
     

   
   
    
     
   
   
email:'xiaowang@easyjf.com',
    
    

   
   
    
     
   
   
sex:'',
     
     

   
   
    
     
   
   
bornDate:'
    
    
     
     1991-4-4
    
    '},
    
    

   
   
    
     
   
   
{id:1,
    
    

   
   
    
     
   
   
name:'小李',
     
     

   
   
    
     
   
   
email:'xiaoli@easyjf.com',
    
    

   
   
    
     
   
   
sex:'',
     
     

   
   
    
     
   
   
bornDate:'
    
    
     
     1992-5-6
    
    '},
    
    

   
   
    
     
   
   
{id:1,
    
    

   
   
    
     
   
   
name:'小兰',
     
     

   
   
    
     
   
   
email:'xiaoxiao@easyjf.com',
    
    

   
   
    
     
   
   
sex:'',
     
     

   
   
    
     
   
   
bornDate:'
    
    
     
     1993-3-7
    
    '}
    
    

   
   
    
     
   
   
];
    
    

   
   
    
     
   
   
var store=new Ext.data.JsonStore({
    
    

   
   
    
     
   
   
data:data,
    
    

   
   
    
     
   
   
fields:["id","name","sex","email",{name:"bornDate",type:"date",dateFormat:"Y-n-j"}]
    
    

   
   
    
     
   
   
});
    
    

   
   
    
     
   
   
var colM=new Ext.grid.ColumnModel([{
    
    

   
   
    
     
   
   
header:"姓名",
     
     

   
   
    
     
   
   
dataIndex:"name",
    
    

   
   
    
     
   
   
sortable:true,
    
    

   
   
    
     
   
   
editor:new Ext.form.TextField()},
    
    

   
   
    
     
   
   
{header:"性别",
     
     

   
   
    
     
   
   
dataIndex:"sex"
    
    

   
   
    
     
   
   
},
    
    

   
   
    
     
   
   
{header:"出生日期",
     
     

   
   
    
     
   
   
dataIndex:"bornDate",
    
    

   
   
    
     
   
   
width:120,
    
    

   
   
    
     
   
   
renderer:Ext.util.Format.dateRenderer('Ymd')},
     
     

   
   
    
     
   
   
{header:"电子邮件",
     
     

   
   
    
     
   
   
dataIndex:"email",
    
    

   
   
    
     
   
   
sortable:true,
    
    

   
   
    
     
   
   
editor:new Ext.form.TextField()}
    
    

   
   
    
     
   
   
]);
    
    

   
   
    
     
   
   
var grid = new Ext.grid.EditorGridPanel({
    
    

   
   
    
     
   
   
renderTo:"hello",
    
    

   
   
    
     
   
   
title:"学生基本信息管理",
     
     

   
   
    
     
   
   
height:200,
    
    

   
   
    
     
   
   
width:600,
    
    

   
   
    
     
   
   
cm:colM,
    
    

   
   
    
     
   
   
store:store,
    
    

   
   
    
     
   
   
autoExpandColumn:3
    
    

   
   
    
     
   
   
});
    
    

   
   
    
     
   
   
});
    
    

上面的程序首先定义了一个包含学生信息的对象数组,然后创建了一个JsonStore,在创建这个store的时候,指定bornDate列的类型为日期date类型,并使用dateFormat来指定日期信息的格式为"Y-n-j"Y代表年,n代表月,j代表日期。定义表格列模型的时候,对于姓名电子邮件列我们使用editor来定义该列使用的编辑器,这里是使用Ext.form.TextField,最后使用new Ext.grid.EditorGridPanel(…)来创建一个可编辑的表格。执行上面的程序可以生成一个表格,双击表格中的姓名、或电子邮件单元格中的信息可以触发单元格的编辑,可以在单元格的文本框中直接编辑表格中的内容,修改过的单元格会有特殊的标记,如下图所示:

为了能编辑性别出生日期列,同样只需要在定义该列的时候指定editor即可。由于出生日期是日期类型,因此我们可以使用日期编辑器来编辑,性别一列的数据不应该让用户直接输入,而应该是通过下拉框进行选择。日期编辑器可以直接使用Ext.form.DateField组件,下拉选择框编辑器可以使用Ext.form.ComboBox组件,下面是实现对性别及出生日期等列信息编辑的代码:

var colM=new Ext.grid.ColumnModel([{
    
    

   
   
    
     
   
   
header:"姓名",
     
     

   
   
    
     
   
   
dataIndex:"name",
    
    

   
   
    
     
   
   
sortable:true,
    
    

   
   
    
     
   
   
editor:new Ext.form.TextField()},
    
    

   
   
    
     
   
   
{header:"性别",
     
     

   
   
    
     
   
   
dataIndex:"sex",
    
    

   
   
    
     
   
   
editor:new Ext.form.ComboBox({transform:"sexList",
    
    

   
   
    
     
   
   
triggerAction: 'all',
    
    

   
   
    
     
   
   
lazyRender:true})
    
    

   
   
    
     
   
   
},
    
    

   
   
    
     
   
   
{header:"出生日期",
     
     

   
   
    
     
   
   
dataIndex:"bornDate",
    
    

   
   
    
     
   
   
width:120,
    
    

   
   
    
     
   
   
renderer:Ext.util.Format.dateRenderer('Ymd'),
     
     

   
   
    
     
   
   
editor:new Ext.form.DateField({format:'Ymd'})},
     
     

   
   
    
     
   
   
{header:"电子邮件",
     
     

   
   
    
     
   
   
dataIndex:"email",
    
    

   
   
    
     
   
   
sortable:true,
    
    

   
   
    
     
   
   
editor:new Ext.form.TextField()}
    
    

   
   
    
     
   
   
]);
    
    

   
   
    
     
   
   
var grid = new Ext.grid.EditorGridPanel({
    
    

   
   
    
     
   
   
renderTo:"hello",
    
    

   
   
    
     
   
   
title:"学生基本信息管理",
     
     

   
   
    
     
   
   
height:200,
    
    

   
   
    
     
   
   
width:600,
    
    

   
   
    
     
   
   
cm:colM,
    
    

   
   
    
     
   
   
store:store,
    
    

   
   
    
     
   
   
autoExpandColumn:3,
    
    

   
   
    
     
   
   
clicksToEdit:1
    
    

   
   
    
     
   
   
});
    
    

 

注意在定义EditorGridPanel的时候,我们增加了一个属性“clicksToEdit: 1” ,表示点击一次单元格即触发编辑,因为默认情况下该值为2,需要双击单元格才能编辑。为了给ComboBox中填充数据,我们使用设置了该组件的transform配置属性值为sexListsexList是一个传统的<select>框,我们需要在html页面中直接定义,代码如下:

<select>
    
    
<option></option>
     
     
<option></option>
     
     
</select>
    
    

执行上面的程序,我们可以得到一个能对表格中所有数据进行编辑的表格了。点击上面的性别一列的单元格时,会出现一个下拉选择框,点击出生日期一列的单元格时,会出现一个日期数据选择框,如图xxxx所示:

(编辑性别列中的数据)

(编辑出生日期列中的数据)

 

那么如何保存编辑后的数据呢?答案是直接使用afteredit事件。当对一个单元格进行编辑完之后,就会触发afteredit事件,可以通过该事件处理函数来处理单元格的信息编辑。比如在http://wlr.easyjf.com这个单用户blog示例中,当我们编辑一个日志目录的时候,需要把编辑后的数据保存到服务器,代码如下:

this.grid.on("afteredit",this.afterEdit,this);
    
    

   
   
    
     
   
   

   
   
    
     
   
   
afterEdit:function(obj){
    
    

   
   
    
     
   
   
var r=obj.record;
    
    

   
   
    
     
   
   
var id=r.get("id");
    
    

   
   
    
     
   
   
var name=r.get("name");
    
    

   
   
    
     
   
   
var c=this.record2obj(r);
    
    

   
   
    
     
   
   
var tree=this.tree;
    
    

   
   
    
     
   
   
var node=tree.getSelectionModel().getSelectedNode();
    
    

   
   
    
     
   
   
if(node && node.id!="root")c.parentId=node.id;
    
    

   
   
    
     
   
   
if(id=="-1" && name!=""){
    
    

   
   
    
     
   
   
topicCategoryService.addTopicCategory(c,function(id){
    
    

   
   
    
     
   
   
if(id)r.set("id",id);
    
    

   
   
    
     
   
   
if(!node)node=tree.root;
    
    

   
   
    
     
   
   
node.appendChild(new Ext.tree.TreeNode({
    
    

   
   
    
     
   
   
id:id,
    
    

   
   
    
     
   
   
text:c.name,
    
    

   
   
    
     
   
   
leaf:true
    
    

   
   
    
     
   
   
}));
    
    

   
   
    
     
   
   
node.getUI().removeClass('x-tree-node-leaf');
    
    

   
   
    
     
   
   
node.getUI().addClass('x-tree-node-expanded');
    
    

   
   
    
     
   
   
node.expand();
    
    

   
   
    
     
   
   
});
    
    

   
   
    
     
   
   
}
    
    

   
   
    
     
   
   
else if(name!="")
    
    

   
   
    
     
   
   
{
    
    

   
   
    
     
   
   
topicCategoryService.updateTopicCategory(r.get("id"),c,function(ret){
    
    

   
   
    
     
   
   
if(ret)tree.getNodeById(r.get("id")).setText(c.name);
    
    

   
   
    
     
   
   
});
    
    

   
   
    
     
   
   
}
    
    

   
   
    
     
   
   
}
    
    

关于可编辑表格控件的详细说明,请参考wlr.easyjf.com中的VIP文档《ExtJS可编辑表格EditorGridPanel详解》。

二十五、    ExtJS2.0实用简明教程》之窗口基本应用

ExtJS中窗口是由Ext.Window类定义,该类继承自Panel,因此窗口其实是一种特殊的面板Panel。窗口包含了浮动、可拖动、可关闭、最大化、最小化等特性。看下面的代码:

var i=0;

 function newWin()

 {       

         var win=new Ext.Window({title:"窗口"+i++,

                             width:400,

                             height:300,

                             maximizable:true});  

         win.show();

 }

Ext.onReady(function(){

         Ext.get("btn").on("click",newWin);

 });
     
     

页面中的html内容:



<input id="btn" type="button" name="add" value="新窗口" />
     
     

执行上面的代码,当点击按钮新窗口的时候,会在页面中显示一个窗口,窗口标题为窗口x”,窗口可以关闭,可以最大化,点击最大化按钮会最大化窗口,最大化的窗口可以还原,如图xxx所示。

二十六、    ExtJS2.0实用简明教程》之窗口分组

窗口是分组进行管理的,可以对一组窗口进行操作,默认情况下的窗口都在默认的组 Ext.WindowMgr中。窗口分组由类Ext.WindowGroup定义,该类包括bringToFrontgetActive hideAllsendToBack等方法用来对分组中的窗口进行操作。

看下面的代码:

var i=0,mygroup;

 function newWin()

 {       

         var win=new Ext.Window({title:"窗口"+i++,

                             width:400,

                             height:300,

                             maximizable:true,

                             manager:mygroup});  

         win.show();

 }

function toBack()

{

         mygroup.sendToBack(mygroup.getActive());

}

function hideAll()

{        

         mygroup.hideAll();

}

Ext.oReay(function(){

         mygroup=new Ext.WindowGroup();

         Ext.get("btn").on("click",newWin);

         Ext.get("btnToBack").on("click",toBack);

         Ext.get("btnHide").on("click",hideAll);

 });
     
     

页面中的html代码

<input id="btn" type="button" name="add" value="新窗口" />

<input id="btnToBack" type="button" name="add" value="放到后台" />

<input id="btnHide" type="button" name="add" value="隐藏所有" />
     
     

执行上面的代码,先点击几次新窗口按钮,可以在页面中显示几个容器,然后拖动这些窗口,让他们在屏幕中不同的位置。然后点放到后台按钮,可以实现把最前面的窗口移动该组窗口的最后面去,点击隐藏所有按钮,可以隐藏当前打开的所有窗口。如下图所示:

二十七、    ExtJS2.0实用简明教程》之对话框

由于传统使用alertconfirm等方法产生的对话框非常古板,不好看。因此,ExtJS提供了一套非常漂亮的对话框,可以使用这些对话框代替传统的alertconfirm等,实现华丽的应用程序界面。 Ext的对话框都封装在Ext.MessageBox类,该类还有一个简写形式即Ext.Msg,可以直接通过Ext.MessageBoxExt.Msg来直接调用相应的对话框方法来显示Ext对话框。看下面的代码:

Ext.onReady(function(){      

         Ext.get("btnAlert").on("click",function(){

                   Ext.MessageBox.alert("请注意","这是ExtJS的提示框");

         });

                   

 });
     
     

Html页面中的内容:



<input id="btnAlert" type="button" value="alert" />
     
     

执行程序,点击上面的“alert按钮,将会在页面上显示如下图所示的对话框。

除了alert以外,Ext还包含confirmpromptprogresswait等对话框,另外我们可以根据需要显示自下定义的对 话框。普通对话框一般包括四个参数,比如confirm的方法签名为confirm ( String title, String msg, [Function fn], [Object scope] ) ,参数title表示对话框的标题,参数msg表示对话框中的提示信息,这两个参数是必须的;可选的参数fn表示当关闭对话框后执行的回调函数,参数 scope表示回调函数的执行作用域。回调函数可以包含两个参数,即buttontext,button表示点击的按钮,text表示对话框中有活动输 入选项时输入的文本内容。我们可以在回调函数中通过button参数来判断用户作了什么什么选择,可以通过text来读取在对话框中输入的内容。看下面的 例子:

Ext.onReady(function(){      

         Ext.get("btn").on("click",function(){

                   Ext.MessageBox.confirm("请确认","是否真的要删除指定的内容",function(button,text){

                             alert(button);

                             alert(text);

                   });

                   });

                   

          });
     
     

Html内容:

<input id="对话框" type="button" value="btn" />
     
     

点击对话框按钮将会出现下面的对话框,然后选择yesno则会用传统的提示框输出回调函数中buttontext参数的内容。

因此,在实际的应用中,上面的代码可以改成如下的内容:

Ext.onReady(function(){      

         Ext.get("btnAlert").on("click",function(){

                   Ext.MessageBox.confirm("请确认","是否真的要删除指定的内容",function(button,text){

                             if(button=="yes"){

                                       //执行删除操作

                                       alert("成功删除");

                             }

                   });

                   });                 

 });
     
     

这样当用户点击对话框中的yes按钮时,就会执行相应的操作,而选择no则忽略操作。

下面再看看prompt框,我们看下面的代码:

Ext.onReady(function(){      

         Ext.get("btn").on("click",function(){

                   Ext.MessageBox.prompt("输入提示框","请输入你的新年愿望:",function(button,text){

                             if(button=="ok"){

                             alert("你的新年愿望是:"+text);

                             }

                             else alert("你放弃了录入!");

                   });

                   });                 

 });
     
     

Html页面:

<input id="btn" type="button" value="对话框" />
     
     

点击上面的对话框按钮可以显示如下图所示的内容,如果点击OK按钮则会输入你输入的文本内容,选择cancel按钮则会提示放弃了录入,如下图所示:

在实际应用中,可以直接使用MessageBoxshow方法来显示自定义的对话框,如下面的代码:

function save(button)

{

         if(button=="yes")

         {

                   //执行数据保存操作

         }

         else if(button=="no")

         {

                   //不保存数据

         }

         else

         {

                   //取消当前操作

         }

}

Ext.onReady(function(){      

         Ext.get("btn").on("click",function(){

                      Ext.Msg.show({

                      title:'保存数据',

                      msg: '你已经作了一些数据操作,是否要保存当前内容的修改?',

                      buttons: Ext.Msg.YESNOCANCEL,

                      fn: save,

                      icon: Ext.MessageBox.QUESTION});

                   });                 

 });
     
     

点击对话框按钮可显示一个自定义的保存数据对话框,对话框中包含yesnocancel三个按钮,可以在回调函数save中根据点击的按钮执行相应的操作,如图xx所示。

二十八、    ExtJS2.0实用简明教程》之与服务器交互

在实际的应用中,表格中的数据一般都是直接存放在数据库表或服务器的文件中。因此,在使用表格控件的时候经常需要与服务器进行交互。ExtJS使用Ajax方式提供了一套与服务器交互的机制,也就是可以不用刷新页面,就可以访问服务器的程序进行数据读取或数据保存等操作。         比如前面在表格中显示xml文档中数据的例子中,就是一个非常简单的从服务器端读取数据的例子,再回顾一下代码:

var store=new Ext.data.Store({
    
    

   
   
    
     
   
   
url:"hello.xml",
    
    

   
   
    
     
   
   
reader:new Ext.data.XmlReader({
    
    

   
   
    
     
   
   
record:"row"},
    
    

   
   
    
     
   
   
["id","name","organization","homepage"])
    
    

   
   
    
     
   
   
});
    
    

因为Sote组件接受一个参数url,如果设置url,则ExtJS会创建一个与服务器交互的Ext.data.HttpProxy对象,该对象通过指定的ConnectionExt.Ajax.request来向服务端发送请求,从而可以读取到服务器端的数据。         经验表明,服务器端产生JSon数据是一种非常不错的选择,也就是说假如服务器的url“student.ejf?cmd=list”产生下面的JSON数据输出:

{results:[{id:1,
    
    

   
   
    
     
   
   
name:'小王',
     
     

   
   
    
     
   
   
email:'xiaowang@easyjf.com',
    
    

   
   
    
     
   
   
sex:'',
     
     

   
   
    
     
   
   
bornDate:'
    
    
     
     1991-4-4
    
    '},
    
    

   
   
    
     
   
   
{id:1,
    
    

   
   
    
     
   
   
name:'小李',
     
     

   
   
    
     
   
   
email:'xiaoli@easyjf.com',
    
    

   
   
    
     
   
   
sex:'',
     
     

   
   
    
     
   
   
bornDate:'
    
    
     
     1992-5-6
    
    '},
    
    

   
   
    
     
   
   
{id:1,
    
    

   
   
    
     
   
   
name:'小兰',
     
     

   
   
    
     
   
   
email:'xiaoxiao@easyjf.com',
    
    

   
   
    
     
   
   
sex:'',
     
     

   
   
    
     
   
   
bornDate:'
    
    
     
     1993-3-7
    
    '}
    
    

   
   
    
     
   
   
]
    
    

   
   
    
     
   
   
}
    
    

则前面显示学习信息编辑表格的store可以创建成下面的形式:

var store=new Ext.data.Store({
    
    

   
   
    
     
   
   
url:"student.ejf?cmd=list",
    
    

   
   
    
     
   
   
reader:new Ext.data.JsonReader({
    
    

   
   
    
     
   
   
root:"result"},
    
    

   
   
    
     
   
   
["id","name","organization","homepage"])
    
    

   
   
    
     
   
   
});
    
    

   
   
    
     
   
   
或者:
     
     

   
   
    
     
   
   
var store=new Ext.data.JsonStore({
    
    

   
   
    
     
   
   
url:"student.ejf?cmd=list",
    
    

   
   
    
     
   
   
root:"result",
    
    

   
   
    
     
   
   
fields:["id","name","organization","homepage"]});
    
    

其中root表示包含记录集数据的属性。         如果在运行程序中需要给服务器端发送数据的时候,此时可以直接使用ExtJS中提供的Ext.Ajax对象的request方法。比如下面的代码实现放服务器的student.ejf?cmd=save这个url发起一个请求,并在params中指定发送的Student对象:

function sFn()
    
    

   
   
    
     
   
   
{
    
    

   
   
    
     
   
   
alert('保存成功');
     
     

   
   
    
     
   
   
}
    
    

   
   
    
     
   
   
function fFn()
    
    

   
   
    
     
   
   
{
    
    

   
   
    
     
   
   
alert('保存失败');
     
     

   
   
    
     
   
   
}
    
    

   
   
    
     
   
   
Ext.Ajax.request({
    
    

   
   
    
     
   
   
url: 'student.ejf?cmd=save’
    
    

   
   
    
     
   
   
success: sFn
    
    

   
   
    
     
   
   
failure: fFn,
    
    

   
   
    
     
   
   
params: { name: '小李',email: ' xiaoli@easyjf.com',bornDate: ' 
     
     
      
      1992-5-6
     
     ',sex: ''}
     
     

   
   
    
     
   
   
});
    
    

关于ExtJS中各控件与服务器端如何交互、Ext.Ajax的详细使用说明等请参考wlr.easyjf.com中的VIP文档《ExtJS中客户端控件与服务器控件交互详解》。

二十九、    ExtJS2.0实用简明教程》之Record

在前面的表格应用中,我们已经知道表格的数据是存放类型为Store的数据存储器中,通过指定表格Gridstore属性来设置表格中显示的数据,通过调用storeloadreload方法可以重新加载表格中的数据。ExtJS中用来定义控件中使用数据的API位于Ext.dd命名空间中,本章我们重点对ExtJS中的数据存储Store进行介绍。

1、Record

首先需要明确是,ExtJS中有一个名为Record的类,表格等控件中使用的数据是存放在Record对象中,一个Record可以理解为关系数据表中的一行,也可以称为记录。Record对象中即包含了记录(行中各列)的定义信息(也就是该记录包含哪些字段,每一个字段的数据类型等),同时又包含了记录具体的数据信息(也就是各个字段的值)。

我们来看直接使用Record的代码:

Ext.onReady(function(){
    
    
var MyRecord = Ext.data.Record.create([
    
    
{name: 'title'},
    
    
{name: 'username', mapping: 'author'},
    
    
{name: 'loginTimes', type: 'int'},
    
    
{name: 'lastLoginTime', mapping: 'loginTime', type: 'date'}
    
    
]);
    
    
var r=new MyRecord({
    
    
title:"日志标题",
     
     
username:"easyjf",
    
    
loginTimes:100,
    
    
loginTime:new Date()
    
    
});
    
    
alert(MyRecord.getField("username").mapping);
    
    
alert(MyRecord.getField("lastLoginTime").type);
    
    
alert(r.data.username);
    
    
alert(r.get("loginTimes"));
    
    
});
    
    

首先使用Recordcreate方法创建一个记录集MyRecordMyRecord其实是一个类,该类包含了记录集的定义信息,可以通过MyRecord来创建包含字段值的Record对象。在上面的代码中,最后的几条语句用来输出记录集的相关信息,MyRecord.getField("username")可以得到记录中username列的字段信息,r.get("loginTimes")可以得到记录loginTimes字段的值,而r.data.username同样能得到记录集中username字段的值。   对Record有了一定的了解,那么要操作记录集中的数据就非常简单了,比如r.set(name,value)可以设置记录中某指定字段的值,r. dirty可以得到当前记录是否有字段的值被更改过等等。

三十、              ExtJS2.0实用简明教程》之Store

Store可以理解为数据存储器,可以理解为客户端的小型数据表,提供缓存等功能。在ExtJS中,GridPanelComboBoxDataView等控件一般直接与Store打交道,直接通过store来获得控件中需要展现的数据等。一个Store包含多个Record,同时Store又包含了数据来源,数据解析器等相关信息,Store通过调用具体的数据解析器(DataReader)来解析指定类型或格式的数据(DataProxy),并转换成记录集的形式保存在Store中,作为其它控件的数据输入。   数据存储器由Ext.data.Store类定义,一个完整的数据存储器要知道数据源(DataProxy)及数据解析方式(DataReader)才能工作,在Ext.data.Store类中数据源由proxy配置属性定义、数据解析(读取)器由reader配置属性定义,一个较为按部就班创建Store的代码如下:

var MyRecord = Ext.data.Record.create([
    
    
{name: 'title'},
    
    
{name: 'username', mapping: 'author'},
    
    
{name: 'loginTimes', type: 'int'},
    
    
{name: 'lastLoginTime', mapping: 'loginTime', type: 'date'}
    
    
]);
    
    
var dataProxy=new Ext.data.HttpProxy({url:"link.ejf"});
    
    
var theReader=new Ext.data.JsonReader({
    
    
totalProperty: "results",
    
    
root: "rows",
    
    
id: "id"
    
    
},MyRecord);
    
    
var store=new Ext.data.Store({
    
    
proxy:dataProxy,
    
    
reader:theReader
    
    
});
    
    
store.load();
    
    

当然,这样的难免代码较多,Store中本身提供了一些快捷创建Store的方式,比如上面的示例代码中可以不用先创建一个HttpProxy,只需要在创建Store的时候指定一个url配置参数,就会自动使用HttpProxy来加载参数。比如,上面的代码可以简化成:

 

var MyRecord = Ext.data.Record.create([
    
    
{name: 'title'},
    
    
{name: 'username', mapping: 'author'},
    
    
{name: 'loginTimes', type: 'int'},
    
    
{name: 'lastLoginTime', mapping: 'loginTime', type: 'date'}
    
    
]);
    
    
var theReader=new Ext.data.JsonReader({
    
    
totalProperty: "results",
    
    
root: "rows",
    
    
id: "id"
    
    
},MyRecord);
    
    
var store=new Ext.data.Store({
    
    
url:"link.ejf",
    
    
proxy:dataProxy,
    
    
reader:theReader
    
    
});
    
    
store.load();
    
    

虽然不再需要手动创建HttpProxy了,但是仍然需要创建DataReader等,毕竟还是复杂,ExtJS进一步把这种常用的数据存储器进行了封装,在Store类的基础上提供了SimpleStoreSimpleStoreGroupingStore等,直接使用SimpleStore,则上面的代码可以进一步简化成下面的内容:

var store=new Ext.data.JSonStore({
    
    
url:"link.ejf?cmd=list",
    
    
totalProperty: "results",
    
    
root: "rows",
    
    
fields:['title',   {name: 'username', mapping: 'author'},
    
    
{name: 'loginTimes', type: 'int'},
    
    
{name: 'lastLoginTime', mapping: 'loginTime', type: 'date'}
    
    
]
    
    
});
    
    
store.load();
    
    

三十一、    ExtJS2.0实用简明教程》之TreePanel基本使用

在应用程序中,我们经常会涉及到要显示或处理树状结构的对象信息,比如部门信息、地区信息,或者是树状的菜单信息,操作系统中的文件夹信息等。   对于传统的html页面来说,要自己实现显示树比较困难,需要写很多的javascript,特别是对于基于Ajax异步加载的树来说,不但涉及到Ajax数据加载及处理技术,还需要考虑跨浏览器支持等,处理起来非常麻烦。ExtJS中提供了现存的树控件,通过这些控件可以在B/S应用中快速开发出包含树结构信息的应用。

TreePanel基本使用

树控件由Ext.tree.TreePanel类定义,控件的名称为treepanelTreePanel类继承自Panel面板。在ExtJS中使用树控件其实非常简单,我们先来看下面的代码

Ext.onReady(function(){
    
    
var root=new Ext.tree.TreeNode({
    
    
id:"root",
    
    
text:"树的根"});
     
     
root.appendChild(new Ext.tree.TreeNode({
    
    
id:"c1",
    
    
text:"子节点"
     
     
}));
    
    
var tree=new Ext.tree.TreePanel({
    
    
renderTo:"hello",
    
    
root:root,
    
    
width:100
    
    
});
    
    
});
    
    

 

代码的第一句使用new Ext.tree.TreeNode类来创建一个树节点,第二句使用树节点的rootappendChild方法来往该节点中加入一个子节点,最后直接使用new Ext.tree.TreePanel来创建一个树面板,要树面板的初始化参数中指定树的root属性值为前面创建的root节点,也就是树根节点。上面的程序执行效果如下图所示:

 

树的节点信息。ExtJS的树控件提供了对这种功能的支持,你只需要在创建树控件的时候,通过给树指定一个节点加载器,可以用来从服务器端动态加载树的节点信息。我们来看下面的代码:

var root=new Ext.tree.AsyncTreeNode({
    
    
id:"root",
    
    
text:"树的根"});
     
     
var tree=new Ext.tree.TreePanel({
    
    
renderTo:"hello",
    
    
root:root,
    
    
loader: new Ext.tree.TreeLoader({url:"treedata.js"}),
    
    
width:100
    
    
});
    
    

 

treedata.js这个url返回的内容如下:

[{
    
    
id: 1,
    
    
text: '子节点1',
     
     
leaf: true
    
    
},{
    
    
id: 2,
    
    
text: '儿子节点2',
     
     
children: [{
    
    
id: 3,
    
    
text: '孙子节点',
     
     
leaf: true
    
    
}]
    
    
}]
    
    

执行上面的程序,可以得到一棵异步加载子节点的树,点击根节点会到服务器端加载子节点,如下图所示:

 

当然上面的程序是一次性加载完了树的所有节点信息,我们也可以实现让每一个节点都支持动态加载的树,只需要在通过服务器请求数据的时候,每次服务器端返回的数据只只包含子节点,而不用把孙子节点也返回即可。比如把上面treedata.js中的内容改为下面的内容:

[{
    
    
id: 1,
    
    
text: '子节点',
     
     
leaf: false
    
    
}]
    
    

也就是节点树中只包含一个子节点,而该子节点通过指定leaf值为false (默认情况该值为false),表示该节点不是一个叶子节点,其下面还有指节点。再执行前面的程序,不断点击子节点可以得到如下图所示的效果:

 

当然这是一个无限循环的树,在实际应用中我们服务器端返回的数据是程序动态产生的,因此不可能每一次都产生leaffalse的节点,如果是叶子节点的时候,则需要把返回的JOSN对象中的leaf设置为true。如下所示:

[{
    
    
id: 1,
    
    
text: '子节点',
     
     
leaf:true
    
    
}]
    
    

事件处理

当然,仅仅能显示一棵树还不够,我们一般还需要在用户点击树节点的时候执行相应的东西,比如打开某一个连接,执行某一个函数等,这就需要使用到事件处理。比如下面的代码:

Ext.onReady(function(){
    
    
var root=new Ext.tree.TreeNode({
    
    
id:"root",
    
    
text:"树的根"});
     
     
var c1=new Ext.tree.TreeNode({
    
    
id:"c1",
    
    
text:"子节点"
     
     
});
    
    
root.appendChild(c1);
    
    
var tree=new Ext.tree.TreePanel({
    
    
renderTo:"hello",
    
    
root:root,
    
    
width:100
    
    
});
    
    
tree.on("click",function(node,event){
    
    
alert("您点击了"+node.text);
     
     
}
    
    
);
    
    
c1.on("click",function(node,event){
    
    
alert("您点击了"+node.text);
     
     
}
    
    
);
    
    

   
   
    
     
   
   
});
    
    

执行上面的程序,当用户点击树控件中的任意节点时,都会弹出一个提示信息框,当用户点击c1这个子节点时,会弹出两次提示信息框。因为我们除了指定treeclick事件响应函数以外,另外又给node节点指定单独的事件响应函数。      当然,如果只是要实现当点击树节点时跳到某一个指定url的功能则非常简单。看下面的代码:

Ext.onReady(function(){
    
    
var root=new Ext.tree.TreeNode({
    
    
id:"root",
    
    
href:"http://www.easyjf.com",
    
    
hrefTarget:"_blank",
    
    
text:"树的根"});
     
     
var c1=new Ext.tree.TreeNode({
    
    
id:"c1",
    
    
href:"http://wlr.easyjf.com",
    
    
hrefTarget:"_blank",
    
    
text:"子节点"
     
     
});
    
    
root.appendChild(c1);
    
    
var tree=new Ext.tree.TreePanel({
    
    
renderTo:"hello",
    
    
root:root,
    
    
width:100
    
    
});
    
    

   
   
    
     
   
   
});
    
    

执行程序,点击树节点,将会在浏览新窗口中打开节点中href指定的链接。

三十二、    ExtJS2.0实用简明教程》之使用树控件TreeNode

ExtJS中,不管是叶子节点还是非叶子节点,都统一用TreeNode表表示树的节点。在ExtJS中,有两种类型的树节点。一种节点是普通的简单树节点,由Ext.tree.TreeNode定义,另外一种是需要异步加载子节点信息的树节点,该类由Ext.tree.AsyncTreeNode定义。 看下面的代码:

Ext.onReady(function(){
    
    
var tree=new Ext.tree.TreePanel({
    
    
renderTo:"hello",
    
    
root:new Ext.tree.AsyncTreeNode({
    
    
text:"根节点"
     
     
}),
    
    
width:100
    
    
});
    
    
});
    
    

执行程序,点击树中的根节点则会一直发现树会尝试加载这个节点的子节点,由这里没有指定树的加载器,所以根节点会变成一直处于加载的状态。如下图所示:

 

对于普通的TreeNode来说,可以通过调用节点的appendChildremoveChild等方法来往该节点中加入子节点或删除子节点等操作。

TreeNodeAsyncTreeNode可以同时使用,比如下面的代码:

Ext.onReady(function(){
    
    

   
   
    
     
   
   
var root=new Ext.tree.TreeNode({
    
    
id:"root",
    
    
text:"树的根"
     
     
});
    
    
var c1=new Ext.tree.TreeNode({
    
    
text:"子节点1"
     
     
})
    
    
var c2=new Ext.tree.AsyncTreeNode({
    
    
text:"子节点2"
     
     
});
    
    
root.appendChild(c1);
    
    
root.appendChild(c2);
    
    
var tree=new Ext.tree.TreePanel({
    
    
renderTo:"hello",
    
    
root:root,
    
    
width:300,
    
    
loader:new Ext.tree.TreeLoader({
    
    
applyLoader:false,
    
    
url:"treedata.js"
    
    
})
    
    
});
    
    

   
   
    
     
   
   
});
    
    
treedata.js中的内容仍然是:
     
     
[{
    
    
id: 1,
    
    
text: '子节点'
     
     
}]
    
    

执行上面的程序可以得到一棵如下图所示的树:

 

另外要在树以外的程序中得到当前选择的节点,可以通过TreePanelgetSelectionModel方法来获得,该方法默认返回的是Ext.tree.DefaultSelectionModel对象,DefaultSelectionModelgetSelectedNode方法返回当前选择的树节点。比如要得到树tree中中当前选择节点,代码如下:

tree.getSelectionModel().getSelectedNode()
    
    

三十三、    ExtJS2.0实用简明教程》之使用树控件TreeLoader

对于ExtJS中的树来说,树加载器TreeLoader是一个比较关键的部件,树加载器由Ext.tree.TreeLoader类定义,只有AsyncTreeNode才会使用TreeLoader。看下面的代码:

Ext.onReady(function(){
    
    

   
   
    
     
   
   
var loader=new Ext.tree.TreeLoader({
    
    
url:"treedata.js"
    
    
});
    
    
var root=new Ext.tree.AsyncTreeNode({
    
    
id:"root",
    
    
text:"根节点",
     
     
loader:loader});
    
    
var tree=new Ext.tree.TreePanel({
    
    
renderTo:"hello",
    
    
root:root,
    
    
width:100
    
    
});
    
    

   
   
    
     
   
   
});
    
    

首先我们使用Ext.tree.TreeLoader来初始化了一个TreeLoader对象,构造函数中的配置参数url表示获得树节点信息的url。然后在初始化根节点的时候我们使用的是AsyncTreeNode,在该节点中指定该节点的laoder为前面定义的loader。执行这段程序,在点击根节点时,会从服务器端指定root节点的子节点信息。      TreeLoader严格来说是针对树的节点来定义的,可以给树中的每一个节点定义不同的TreeLoader,默认情况下,如果一个AsyncTreeNode节点在准备加载子节点的时候,如果该节点上没有定义loader,则会使用TreePanel中定义的loader作为加载器。因此,我们可以直接在TreePanel上面指定loader属性,这样就不需要给每一个节点指定具体的TreeLoader了。因此,上面的代码可以改成如下所示的内容:

三十四、    ExtJS2.0实用简明教程》之自定义TreeLoader

ExtJS自己的TreeLoader中,当要实现从远程服务器端异步加载树节点信息的时候,都是通过请求服务器上的某一个URL来进行的,这个URL返回下面的信息:

[{
    
    
id: 1,
    
    
text: 'A leaf Node',
    
    
leaf: true
    
    
},{
    
    
id: 2,
    
    
text: 'A folder Node',
    
    
children: [{
    
    
id: 3,
    
    
text: 'A child Node',
    
    
leaf: true
    
    
}]
    
    
}]
    
    

假如我们是直接通过类似DWREasyJWeb的远程脚本引擎在客户端直接调用服务器的业务方法,直接跳过了WEB(不需要StrutsJSP或其它Web层的代码)这一层,这时我们没有URL,这时该怎么办呢?这就需要使用到自定义的TreeLoader,下面我们通过一个实例来做简单的讲解。  看服务器端的ITopicCategoryService  public interface ITopicCategoryService {  List loadCategory(Long id);  }     loadCategory方法返回一个类型为Node的列表,也就是返回指定id的下级分类信节点信息,Node对应树节点的信息,代码如下:

public class Node {
    
    
private TopicCategory category;
    
    
Node(TopicCategory category) {
    
    
this.category = category;
    
    
}
    
    
public String getId() {
    
    
return category.getId().toString();
    
    
}
    
    
public boolean getLeaf() {
    
    
return category.getChildren().size() < 1;
    
    
}
    
    
public String getText() {
    
    
return category.getName();
    
    
}
    
    
public String getQtip() {
    
    
return category.getName();
    
    
}
    
    
}
    
    

Node在这里相当于一个简单适配器,其实就是把数据库中的日志分类实体适配成包树节点对象。

ITopicCategoryService发布成可供客户端远程调用,使用EasyJWeb的话引如下面三个js

<script type="text/javascript" src="/ejf/easyajax/prototype.js"></script>
    
    
<script type="text/javascript" src="/ejf/easyajax/engine.js"></script>
    
    
<script type="text/javascript" src="/ejf/easyajax/topicCategoryService.js"></script>
    
    

使用DWR的话引入下面的两个js

<script type="text/javascript" src="/dwr/dwr/engine.js "></script>
    
    
<script type="text/javascript" src="/dwr/dwr/util.js "></script>
    
    
<script type="text/javascript" src="/dwr/dwr/interface/ topicCategoryService.js "></script>
    
    

这样我们可以在页使用下面的javascrpt来从服务器端获得某一个节点的子节点信息,代码如下:

function test()
    
    
{
    
    
topicCategoryService.loadCategory(1,function(ret)
    
    
{
    
    
alert("一共有"+ret.length+"个子节点");
     
     
}
    
    
}
    
    

如何让ExtJS的树面板能通过这个远程web脚本方法topicCategoryService.loadCategory来加载异步加载树节点信息呢?其实很简单,跟一般的使用没什么两样,树面板TreePanel的代码如下:

var tree = new Ext.tree.TreePanel({
    
    
autoScroll:true,
    
    
animate:true,
    
    
width:'100px',
    
    
height:'300px',
    
    
enableDD:true,
    
    
containerScroll: true,
    
    
loader: loader
    
    
root: new Ext.tree.AsyncTreeNode({
    
    
text: '日志分类',
     
     
id:'root'
    
    
});
    
    
});
    
    

然后区别是在loader部分,使用远程Web调用来加载树节点的loader,代码如下:

var loader=new WebInvokeTreeLoader({
    
    
fn:topicCategoryService.loadCategory
    
    
});
    
    
loader.on("beforeload",function(l,node){
    
    
l.args[0]=(node.id!='root'?node.id:"-1");
    
    
});
    
    

再回顾一下传统的直接通过url加载树节点的TreeLoader代码,如下所示:

var loader=new Ext.tree.TreeLoader({
    
    
url:'/topicCategory.ejf?cmd=getCategory&pageSize=-1&treeData=true'
    
    
});
    
    
loader.on("beforeloader",function(loader,node){
    
    
loader.baseParams.id=(node.id!='root'?node.id:"");
    
    
});
    
    

区别在于,远程脚本调用方式加载树节点信息使用的是WebInvokeTreeLoader,需要通过fn属性来指定用于加载数据的远程方法,并在beforeload事件处理器设置参数远程方法调用的参数值。而传统的树节点加载器是Ext.tree.TreeLoader,需要指定一个url来获得json数据。       WebInvokeTreeLoader是自定义的树加载器,代码其实比较简单,你可以自己写一个。本方案仅供参考,关于WebInvokeTreeLoader的源代码我已经传到了我用ExtJS开发的Blog示例网站上了,仅供VIP会员浏览,有兴趣的朋友可跟我联系。

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值