欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ExtJs之数据和ComboBox控件

程序员文章站 2022-05-13 14:38:51
...

 

一、如何获取数据

在ExtJs中获取数据主要靠下面四个类: Ext.data.DataProxy、Ext.data.Record、Ext.data.DataReader、Store。下面对这三个类做个简单的介绍。

 

 

DataProxy:获取想要的数据。通过他能得到来自不同地方的数据,如数组、远程服务器,并组织成不同的格式。

 

 

DataReader:定义数据项的逻辑结构,一个数据项有很多列,每列的名称是什么,分别是什么数据类型,都由该类来定义。另外,还负责对不同格式的数据进行读取和解析。在这里用到了Ext.data.Record类来定义具体的列类型。

 

Store:存储器,用于整合Proxy和Reader,控件索取数据时通常和他打交道。

 

 

 

二、Ext.data.DataProxy 类

proxy是代理的意思,很多时候,聪明的架构师和设计者为了屏蔽底层的差异,给用户提供一个统一的访问接口,会设计一个名为“proxy”的类。这种设计哲学在架构中普通应用,并且解决了很多实际问题,代码也变得更加优雅,并有效降低代码侵入。

Ext.data. DataProxy就是来源于这样一种灵感。

Ext.data.DataProxy 是获取数据的代理,数据可能来自于内存,可能来自于同一域的远程服务器数据,更有可能来自于不同域的远程服务器数据。

 

 

 

但是,在实际应用中,我们不会直接使用Ext.data.DataProxy,而是使用他的子类:MemoryProxy、HttpProxy和ScriptTagProxy,他们的作用分别是:

MemoryProxy:获取来自内存的数据,可以是数组、json或者xml。

HttpProxy:使用HTTP协议通过ajax 从远程服务器获取数据的代理,需要指定url。

ScriptTagProxy:功能和HttpProxy一样,但支持跨域获取数据,只是实现时有点偷鸡摸狗。

 

 

 

因为数据最终要显示在ComboBox 中,所以我们以ComboBox 为中心进行设计。大家应该知道,下拉列表框有两个值,一个是显示值,另一个是实际值,也就是说,一个数据项包含两列:显示值列和实际值列。我们定义一个用来保存城市名称的二维数组:

 

 

var cities = [["1", "沈阳"], ["2", "大连"], ["3", "鞍山"], ["4", "辽阳"]];

在二维数组中,每一个城市保存了两个值:值一表示城市编号,作为实际值,值二表示城市名称,作为显示值。然后,我们将data 构建出一个MemoryProxy对象:

 

 

var mp = new Ext.data.MemoryProxy(cities);

 

 

 

三、Ext.data.DataReader 类

 

DataReader 从来不是单独行动的,他没有太多的自主权,总是看DataProxy行事。总体来说,DataReader 用来定义数据项(行)的逻辑结构,主要信息有:列的逻辑名称(name)、列的数据类型(type)、列与数据源的索引映射(mapping)等,另外,还包含一些元数据,如分页信息。

实际上,每一个数据项都是一个Ext.data.Record(记录)对象,而数据项的列信息则是通过Ext.data.Record来定义的。Ext.data.Record并没有固定的结构,他保存的是一个json对象数组,数组的元素个数由列的数量来决定。在上面的例子中,城市包含ID 和名称,所以,必须在数组中定义两个元素,基本就是这个样子:

 

 

	var myRecord = Ext.data.Record.create([{
				name : 'cid',
				type : 'int',
				mapping : 0
			}, {
				name : 'cname',
				type : 'string',
				mapping : 1
			}]);

我们定义了一个myRecord的结构,通过Ext.data.Record.create创建,参数是一个json对象数组,name 和type 分别表示每一列的名称和数据类型,mapping 是列值与数组元素的映射关系。 

 

 

Record 创建好后,必须和DataReader 关联,DataReader 也同样有三个子类:Ext.data.ArrayReader、Ext.data.JsonReader、Ext.data.XmlReader。我之前说过DataReader 从来不单独行动,使用哪一个子类主要取决于DataProxy中封装的数据类型,如果是数组,则使用Ext.data.ArrayReader;如果是json,则使用Ext.data.JsonReader;如果是xml,则使用Ext.data.XmlReader。

 

在本例中,我们处理的数据类型是数组,所以自然要使用ArrayReader。

 

var myReader = new Ext.data.ArrayReader({}, myRecord);

构造ArrayReader 对象时,构造函数的第一个参数就是元数据,第二个参数则是Record。也可以一步到位: 

 

 

var myReader = new Ext.data.ArrayReader({}, [
{name: "cid", type: "int", mapping: 0},
{name: "cname", type: "string", mapping: 1}
]);

 

 

四、Ext.data.Store 类

这个类相对简单,不需要面对数据和结构,只是把DataProxy和DataReader 整合在一起,这样一来,数据有了,结构有了,俨然就是一张数据表,想一想数据库中的物理表是不是就是这样的呢?嗯,非常像。

典型的写法像这样:

var store = new Ext.data.Store({
    proxy: proxy,
    reader: reader
});

到了这一步,别以为大功告成了,其实这时候数据并没有加载到Store中,默认情况下,Store采取延时加载,必须显式调用load()方法,当然,我们也可以采取即时加载策略,按如下配置即可: 

var store = new Ext.data.Store({
    proxy: proxy,
    reader: reader,
    autoLoad: true //即时加载数据
});

我们画张图,用来描述这三个类之间的关系。

ExtJs之数据和ComboBox控件
            
    
    博客分类: ExtJS ExtJsDataProxyDataReaderStore 
可以看出,Ext.data.Store的主要目的是在内存中建立一张数据表,填充到组件中,这些组件形态也千差万别,最典型的就是ComboBox 和GridPanel。

 

 

五、下拉列表框

下拉列表框被定义成ComboBox 类,位于Ext.form命名空间,和Button不同,他是一个表单域组件,常用于表单中。

我们有一个这样的ComboBox,该组件用来显示辽宁的城市。

ExtJs之数据和ComboBox控件
            
    
    博客分类: ExtJS ExtJsDataProxyDataReaderStore 
看起来和select标记别无二致,只是更加漂亮了。  

 

一起来熟悉一个比较典型的ComboBox的定义方法:

var combobox = new Ext.form.ComboBox({
			renderTo : Ext.getBody(),
			triggerAction : "all",
			store : store,
			displayField : "cname",
			valueField : "cid",
			mode : "local",
			emptyText : "请选择辽宁城市"
		});

嘿嘿,如果不解释您一定会愣上半天,有时候真不习惯Extjs中属性名称的定义风格,也许只怪我们的头发太长见识太少,来认识一下吧。

triggerAction:是否开启自动查询的功能,为all表示不开启,为query表示开启,默认为query;

store:不用解释了,和前面的Ext.data.Store对象挂勾,定义数据源;

displayField:关联Record的某一个逻辑列名作为显示值,本例为城市名称;

valueField:关联Record的某一个逻辑列名作为实际值,本例为城市ID;

mode:可选值有local和remote,如果数据来自本地,用local,如果数据来自远程服务器,必须用remote,默认为remote;

emptyText:没有选择任何选项的情况文本框中的默认文字。

 

请理解并记住这个基本的用法,很多东西都是这样巩固消化的。当我们面对如海水般涌来的信息,第一感觉就是无所适从,继而惊惶失措,夺路而逃,于是被永远挡在真理的大门之外。成功和失败,只在一念之间。

抓住核心点之后,慢慢扩展,知识架构便会越来越丰满,因为把握好了整个知识点的精髓,再怎么变化,都不至于迷路。 

 

六、得到下拉列表框的值

下拉列表框(ComboBox)有两个值,显示值和实际值。显示值为用户提供了更为直观和理想的体验,而实际值则会传送到服务器,供服务器处理。

ComboBox定义了两个方法,其中,getValue()用于返回实际值,getRawValue()用于返回显示值。

我在页面上放置了一个按钮,点击按钮显示下拉列表框的值:

var btn = new Ext.Button({
			text : "列表框的值",
			renderTo : Ext.getBody(),
			handler : function() {
				Ext.Msg.alert("值", "实际值:" + combobox.getValue() + ";显示值:"
								+ combobox.getRawValue());
			}
		});

 

七、源代码

下面是本章示例的源程序:

Ext.onReady(function() {
			cmp();
		});

var cmp = function() {
	// 1. 定义本地静态数据
	var cities = [["1", "沈阳"], ["2", "大连"], ["3", "鞍山"], ["4", "辽阳"]];
	// 2. 根据数据定义内存代理
	var mp = new Ext.data.MemoryProxy(cities);
	// 3. 创建记录格式
	var myRecord = Ext.data.Record.create([{
				name : 'cid',
				type : 'int',
				mapping : 0
			}, {
				name : 'cname',
				type : 'string',
				mapping : 1
			}]);
	// 4.把数据按照创建的记录格式进行组合
	var myReader = new Ext.data.ArrayReader(mp, myRecord);
	//var reader = new Ext.data.ArrayReader({}, myRecord);
	
	// 5.把数据按照一定格式组成的数据组传入缓存
	var myStore = new Ext.data.Store({
				proxy : mp,
				reader : myReader,
				autoLoad : true
			});
	// store.load(); 如果在Store配置信息中使用autoLoad:true,就可以不用此方法.
	// 5.创建下拉列表,把数组写入下接列表
	var myCb = new Ext.form.ComboBox({
				id : "myCb1",
				store : myStore,
				title : "辽宁省下属市",
				emptyText : "辽宁省下属市",
				displayField : "cname",
				valueField : "cid",
				triggerAction : "all",
				mode : "local",
				renderTo : Ext.getBody()
			});
	// 6.创建按钮,实现读取下拉列表
	var myBtn = new Ext.Button({
				id : "myBtn1",
				type : "button",
				text : "所选城市",
				renderTo : Ext.getBody(),
				handler : function() {
					if (myCb.getValue() == "") {
						Ext.Msg.alert("提示","请做出选择");
						myCb.focus(true);
					} else {
						Ext.Msg.alert("值", "实际值:" + myCb.getValue() + ";显示值:"
										+ myCb.getRawValue());
					}
				}
			});
}

 

 

 

 

  • ExtJs之数据和ComboBox控件
            
    
    博客分类: ExtJS ExtJsDataProxyDataReaderStore 
  • 大小: 52.4 KB
  • ExtJs之数据和ComboBox控件
            
    
    博客分类: ExtJS ExtJsDataProxyDataReaderStore 
  • 大小: 4.9 KB