第6章数据传输的标准化解析.docx

上传人:b****4 文档编号:4878845 上传时间:2022-12-11 格式:DOCX 页数:16 大小:60.15KB
下载 相关 举报
第6章数据传输的标准化解析.docx_第1页
第1页 / 共16页
第6章数据传输的标准化解析.docx_第2页
第2页 / 共16页
第6章数据传输的标准化解析.docx_第3页
第3页 / 共16页
第6章数据传输的标准化解析.docx_第4页
第4页 / 共16页
第6章数据传输的标准化解析.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

第6章数据传输的标准化解析.docx

《第6章数据传输的标准化解析.docx》由会员分享,可在线阅读,更多相关《第6章数据传输的标准化解析.docx(16页珍藏版)》请在冰豆网上搜索。

第6章数据传输的标准化解析.docx

第6章数据传输的标准化解析

第6章数据传输的标准化

ExtJS除了组件丰富外,另外一个特点就是数据传输的标准化。

那么,这样做,有什么好处?

为什么要这样做呢?

本章将为你解答这些问题。

在搞清楚这些问题之后,就要考虑怎么去实现了。

本章将通过简单的CMS系统来演示数据传输的标准化的基本的实现思路。

1

2

3

4

5

6

6.1标准化的数据传输是什么

在本书所说的标准化的数据传输主要是指,使用代理提交数据时,格式必须统一化标准化,而服务器端在处理提交的数据后,返回的数据格式必须是标准化的数据。

6.2为什么要实现数据传输的标准化

假设要使用ExtJS开发一个非常庞大的复杂的系统,在项目组里有许多开发人员,其中,开发人员A习惯以A方式提交和返回数据,而开发人员B则习惯以B方法提交和返回数据,而开发人员C则需要根据开发人员A和B的数据请求和数据格式返回数据,那么,开发人员C就必须根据开发人员A和B各自喜好的方式去获取提交数据和返回不同格式的数据。

可以想象得到,开发人员C是多么的悲催,估计杀人的想法都有了。

姑且勿论是否存在开发人员C这样的悲情人物,当系统开发完成,进入后期维护的时候,维护人员面对的就是一堆不同格式的提交数据和返回数据,这无疑大大增加了维护成本。

如果以上两种情况,还不足以说明问题的话,那么,当公司需要针对某个客户的需求,需要修改开发平台,进行迁移的时候,就得根据不同格式去进行迁移,这无疑也增大了迁移的开发成本。

因此,实现数据传输的标准化是很有必要的。

6.3标准化数据传输的好处

根据6.1节的描述,标准化数据传输的好处之一就是,服务器端的数据处理可以实现统一化标准化,无论客户端提交的数据是什么,只需要根据标准化统一化的处理过程,就能把数据分离出来并进行相应处理。

通过数据处理的标准化统一化,就可以大大减少重复代码,提高代码的可重用性,而这,无疑是大大的利好。

重复代码的减少,无疑会提高代码的可维护性,而这也是利好之一。

由于客户端接收的是以标准格式的返回的数据,因而,无论服务器端平台怎么变化,只要以这种标准化格式返回数据,客户端代码不需要做任何修改,就能正确处理返回的数据。

因而,标准化的数据传输,对于项目开发平台的迁移,也是有相当大的好处的。

6.4如何实现标准化

既然实现数据传输的标准化是好的,那么如何去实现呢?

这,首先得从ExtJS的数据传输方式说起。

6.4.1ExtJS的主要数据传输方式

ExtJS主要的数据传输方式有Ajax、JsonP、表单和代理这4种方式。

JsonP是用来处理跨域请求的,由于跨域请求会受到另一个域平台返回数据格式的影响,因而只能针对性的进行处理,不一定能以标准化格式进行处理,所以本节就不把它考虑在内了。

不过,如果跨域的平台也是以这种统一的标准化的格式返回数据,那真可以偷着笑了。

下面来研究一下Ajax、表单和代理这三种传输方式的提交格式和返回格式。

1.Ajax

Ajax可以说是ExtJS最基本的数据传输方式,无论是表单的提交或是代理,都是以这为基础的。

当然,表单也可以使用传统的HTML方式来提交,而这,已不在本书讨论的范围,因而,本书所说的表单提交,都是指以Ajax方式提交的表单。

Ajax方式的数据传输,提交数据比较灵活,这个可根据不同的需要灵活处理。

而对于提交后返回的数据,则可以使用统一的数据格式,以便客户端进行处理。

2.表单

在ExtJS中,如果没有特殊设置,表单是以Ajax方式提交,而这,实际上与传统的HTML表单提交区别不大。

因而,对于接收表单的数据,还是要按习惯的方式处理。

而对于表单提交后返回的数据格式,是有特殊要求的,这主要包括两种格式。

第一种格式是字段有错误时的格式,格式如下:

{

success:

false,

errors:

{

field1:

"错误信息",

field2:

"错误信息",

...

}

}

在以上格式中,属性success的值必须是false,以表明表单的提交存在错误,而属性errors则包含了存在错误的字段以及错误信息。

格式中的field1、field2对应的就是表单中字段的配置项name的值。

第二种格式则是没有字段错误,但存在其他错误或者是提交成功后的返回格式,格式如下:

{

success:

true或false,

msg:

"信息"

}

以上格式中,属性success是必须的,true表示表单提交成功,false则表示提交失败。

属性msg则可根据项目的规定或自己的喜好进行定义,但必须与代理使用的属性相同,从而实现统一的返回格式。

3.代理

代理无论是提交还是返回的数据格式,都是有固定格式,但为了保持一定的灵活性,提交格式可由配置项进行定义,如Ext.data.writer.Json的encode配置项,可决定提交数据是以流形式提交还是以HTTP变量的形式提交。

因而,标准化提交格式主要的方式就是使用固定的配置项。

代理的返回格式基本上是固定的,主要格式如下:

{

success:

true或false,

total:

数据总数,

data:

[...],

msg:

"信息"

}

以上格式中的4个属性都可通过配置项进行修改,因而,为了实现标准化,必须固定这些配置项。

6.4.2扩展代理,以实现数据传输的标准化

从ExtJS的主要数据传输方式可以了解到,标准化格式其中一个重点就是标准化代理的提交格式和返回格式,而这,可通过扩展代理来实现。

对代理进行扩展,主要目的就是固定Reader和Writer的配置项,这样,不但实现了数据传输的标准化,还可减少重复代码,提高代码的可重用性。

在实现之前,要先了解哪些配置项是需要修改的,哪些配置项是不需要修改。

对于提交格式,主要是指Ext.data.writer.Json的配置项,包括以下这些:

❑allowSingle:

是否允许提交单个记录,默认值是true,允许提交单个记录。

如果允许提交单个记录,在服务器端,就要对提交的数据先判断提交的是对象还是数组,才能进一步对数据进行处理,这无疑增大了处理难度。

因而,应该毫不犹豫的把它设置为false,无论是单个记录还是多个记录,统一以数组的形式提交到服务器,便于服务器进行处理。

❑encode:

决定数据以什么形式提交,默认值为false,是以数据流形式提交到服务器。

因而,在服务器,需要以读取数据流(类似于读取上传文件)的方式来获取数据,这对许多开发人员来说,会非常的不习惯,也不方便,因而,要毫不犹豫的修改为true,以习惯的HTTP变量方式提交。

❑root:

设置了encode为true后,在服务器使用哪个变量名来获取数据,就需要使用该配置项来定义。

我比较习惯定义root的值为data,这样,在服务器就可以使用data来获取数据。

这个,可根据设计要求或个人喜好来定义。

❑writeAllFields:

是否只提交修改过的字段。

默认值为true,无论字段是否修改过,都会提交。

我习惯提交全部字段,因为在服务器单独提取个别修改字段,不如整体处理来得方便。

对于返回格式,主要是指Ext.data.reader.Json的配置项,包括以下这些:

❑messageProperty:

用来定义返回的数据中,可获取到响应信息的属性,也就是用来定义6.4.1节代理格式中的msg属性的配置项。

这个可根据设计要求或个人喜好设置,我个人偏好于使用msg作为属性。

❑root:

用来定义返回的数据中,可获取到记录的属性。

也就是用来定义6.4.1节代理格式中的data属性的配置项。

这个可根据设计要求或个人喜好设置,我个人偏好于使用data作为属性。

❑successProperty:

用来定义返回的数据中,可获取到数据返回是否成功的属性。

也就是用来定义6.4.1节代理格式中的success属性的配置项。

默认值就是success,一般情况下,不建议修改该属性。

❑totalProperty:

用来定义返回的数据中,可获取到记录总数的属性。

也就是用来定义6.4.1节代理格式中的total属性的配置项。

默认值就是total,一般情况下,不建议修改该属性。

从以上介绍可以了解到,需要定义的配置项主要包括encode、root、allowSingle、messageProperty。

明确了要统一的配置项之后,就可实现扩展代理(以下称为格式化代理)了。

但在实现之前,要考虑是把格式化代理定义在Ext.ux命名空间下,还是定义在SimpleCMS.ux命名空间下。

这两种命名方式的主要区别就在于目录的位置。

一般情况下,通用的扩展最好是定义在Ext.ux命名空间下,这样便于区分,但存在的问题是这些扩展会分布在ext\src\ux目录下,不便于维护,例如,在当前项目,把扩展放到ext\src\ux目录,由于要展开的目录比较深,要找出相应的类还是比较费劲的。

如果放在SimpleCMS.ux命名空间下,最大的问题就是要使用到另一个项目的时候,需要修改命名空间。

以我的经验来说,我偏好SimpleCMS.ux命名空间,主要原因就是便于维护,而这个问题的重点就是Ext本身扩展就很多,因而,在ext\src\ux目录下本身就有很多目录和文件,要在里面找项目的文件比在app\ux目录下找要费劲。

而且考虑到如果要把扩展复制到另外一个项目,直接把app\ux目录复制过去,然后修改命名空间就可以了,而不需要在ext\src\ux目录下一个个找出来再复制过去。

当然,这个问题,可通过预先把所有自己的扩展整合到一个目录,再进行复制的方式来解决,但总的来说,还是不如在app\ux目录下定义来得方便。

提示把自己的扩展放在app\ux的目录的想法来自于ExtJS4.2的示例SimpleTask,然后经过实践,感觉这样确实是方便多了,在解决方案资源管理器中找扩展要依次展开ext→src→ux目录,感觉比较烦人。

建议多点研究一下ExtJS中的示例,会获益良多的。

想法确定后,就可以在Scripts\app目录下依次添加目录ux→data→proxy,然后在proxy目录下添加添加一个名为Format.js的JavaScript文件来定义格式化代理。

这样做的目的是为了将类名定义为SimpleCMS.ux.data.proxy.Format,以符合ExtJS的类命名规则,这个可参考SimpleCMS.ux.data.proxy.Format的父类Ext.data.proxy.Ajax的命名规则,Ajax.js文件就是在data\proxy目录下。

当然,如果图方便,不按照这个命名规则命名也行。

在类名和父类都已经清楚的情况下,要写出类的定义代码也就不难了,代码如下:

Ext.define('SimpleCMS.ux.data.proxy.Format',{

extend:

'Ext.data.proxy.Ajax',

})

为了能像Ext.data.proxy.Ajax哪样,在定义代理的时候,可使用值为ajax的type配置项来指定使用Ext.data.proxy.Ajax代理,就必须定义别名,也就是定义alias配置项。

在Ext.data.proxy.Ajax中,别名的定义为“proxy.ajax”,再观察一下其他代理类的别名定义,都需要添加“proxy.”作为前缀,因而,在格式化代理的别名中添加前缀是必不可少的。

而我打算用format作为格式化代理的别名,因而,格式化代理的完整别名会是“proxy.format”。

别名定义好以后,就要统一读取器的格式了,要统一的配置项主要包括root和messageProperty,代码如下:

reader:

{

type:

'json',

root:

"data",

messageProperty:

"msg"

},

代码中,由type配置项可以知道,这里将使用JSON读取器(Ext.data.reader.Json),返回格式中,数据必须在data属性中,而信息则包含在msg属性中。

接下来,要统一的是编写器的格式,主要包括的配置项是encode、root和allowSingle,代码如下:

writer:

{

type:

"json",

encode:

true,

root:

"data",

allowSingle:

false

},

从代码可以看到,编写器将使用JSON编写器(Ext.data.writer.Json),提交的数据将以HTTP变量方式提交,提交的变量的名称是data。

无论是一个数据还是多个数据,都将以数组形式提交。

下面做一个简单的测试来测试一下这个格式化代理。

测试很简单,建立一个模型,然后进行一些操作就行了。

打开application.js文件,添加launch方法,在方法内添加以下代码:

launch:

function(){

Ext.define('Test',{

extend:

'Ext.data.Model',

fields:

['id','text'],

proxy:

{

type:

'format',

api:

{

create:

'/test/add',

read:

'/test/',

update:

'/test/update',

destroy:

'/test/delete'

}

}

});

Test.load(1,{

success:

function(rec,opts){

console.log(rec);

rec.destroy();

}

})

vara=Ext.create('Test',{text:

'test'});

a.save();

}

代码中,定义了一个带有id和text这两个字段的模型Test,模型的代理将使用刚刚定义的格式化代理。

配置项api为代理定义了执行添加、加载、修改和删除等操作时的地址。

接着,调用模型的load方法加载数据。

如果数据加载成功,则在Firebug的控制台输出数据,并调用destroy方法删除数据。

最后是创建一个新的模型实例,然后调用save方法保存它。

要代码顺利运行,还得在requires配置项中加入对格式化代理的引用,不然就会出现找不到文件的错误。

注意如果在Firebug中看到如图61所示的警告信息和错误信息,说明在定义类的时候,没在requires配置项中加入对所需类的引用。

例如,图中顶部的警告信息说明没有引用标签面板(Ext.tab.Panel),而底部的错误信息就说明找不到格式化代理,这些都是未能正确设置requires配置项造成的。

如果看到这些警告信息或错误信息,加入对所需类的引用就行了。

在本书后续的讲解中,将不再提醒大家将所需类加入到requires配置项中,大家自行处理就行了。

图61由于未引用类,在Firebug输出的警告信息和错误信息

接下来还要在Controllers目录创建一个名为TestController的空MVC控制器,在控制器内,先加入以下代码引用Json.NET:

usingNewtonsoft.Json;

usingNewtonsoft.Json.Linq;

注意在后续的讲解中,将不再提醒大家在类中加入引用。

如果VisualStudio提示找不到对象,大家根据具体情况加入相应的引用就行了。

然后将Index方法的返回值修改为JObject,再加入以下代码:

returnnewJObject(

newJProperty("success",true),

newJProperty("data",newJArray(

newJObject(

newJProperty("id",1),

newJProperty("text","test")

))

);

代码将根据返回格式创建一个JSON对象,对象内包含了success属性和data属性。

好了,现在在VisualStudio主菜单选择生成→重新生成解决方案来生成解决方案。

等左下角提示全部重新生成已成功后,在主菜单选择调试→开始执行(不调试)在浏览器打开应用程序。

如果这时候,Firebug还没打开,就先打开Firebug,再刷新一次页面。

当应用程序执行后,会在Firebug的控制台看到如图62所示的输出信息。

从输出信息可以看到,测试代码发送了3个请求,第一个请求是用来加载id为1的数据,第二个请求是添加记录的请求,第三个请求为删除记录的请求。

在信息中还显示了一个对象,这就是第一个请求返回后根据返回的数据创建的模型实例。

图62测试格式化代理时控制台显示的信息

在这里,关注的是数据的格式,因而,先展开第一个请求,然后切换到响应标签页,会看到服务器返回了以下的数据:

{

"success":

true,

"data":

[

{

"id":

1,

"text":

"test"

}

]

}

根据格式可以知道,这正是格式化代理要求的数据返回格式,如果修改TestController的代码,将success的值修改为false,或将属性名称data修改为其他名称,客户端就能根据返回的数据创建模型实例了。

下面展开第二、三个请求,并切换到Post标签页,会看到以下提交数据:

//第二个请求提交的数据

data[{"text":

"test"}]

//第三个请求提交的数据

data[{"id":

1,"text":

"test"}]

从提交的数据格式可以看到,提交参数data正是格式化代理中,编写器定义的root配置项的值。

再看看提交值,都是数组形式,这说明allowSingle配置项起作用了。

在服务器,就可使用统一的数据处理方式来处理数据了。

从测试结果来看,格式化代理的运作一切正常。

对于Store、模型等比较多的项目,这可减少不少定义代理时的重复代码。

当然,更大的好处是服务器可以统一处理提交数据和返回固定格式的数据。

6.4.3在服务器统一输出接口

和客户端一样,在服务器的方法内,每次返回数据的时候,都要按照返回格式写一次代码,因而存在不少重复代码。

为了减少重复代码,最好的方式当然是实现统一的输出接口。

下面来实现这个。

在解决方案添加一个名为Helper的目录,并在目录内创建一个名为ExtJS的类。

类名定义为ExtJS,可以清楚的表明这是一个用来处理ExtJS数据的类。

接下来,在类中定义一个名为WriterJObject,返回值为Jobject的静态方法,该方法将根据返回格式返回数据。

根据6.4.1节可以知道,返回格式中的属性主要包括success、errors、total、msg和data这五个属性。

在这五个属性中,除了属性success是必须的外,其他属性都是可选的。

因而,可以使用以下方式来定义WriterJObject的参数:

publicstaticJObjectWriterJObject(

boolsuccess,

JObjecterrors=null,

int?

total=null,

stringmsg=null,

objectdata=null

{

}

代码中,定义了默认值的参数叫做可选参数,这样,在调用方法时,就不用指定不必要的参数,而使用这些参数的默认值。

这样做的好处是,不用根据不同格式,去定义一堆参数不同的重载方法。

而且,在方法内,如果检查到参数的值是默认值null,也就不用把这参数写入返回的对象中。

由于data参数返回的数据类型可能是JArray,也可能是JObject,所以在这里将它设置为object,就能分别处理这两种数据了。

在方法内,除了必须在返回的Jobject对象中加入success属性外,其他属性,如果值为null,则不用加入JObject中,具体代码如下:

JObjectjo=newJObject(

newJProperty("success",success)

);

if(errors!

=null)

{

jo.Add(newJProperty("errors",errors));

}

if(total!

=null)

{

jo.Add(newJProperty("total",total));

}

if(msg!

=null)

{

jo.Add(newJProperty("msg",msg));

}

if(data!

=null)

{

jo.Add(newJProperty("data",data));

}

returnjo;

好了,现在来测试一下该方法。

切换到TestController控制器,将Index方法的代码修改为以下代码:

returnExtJS.WriterJObject(true,data:

newJObject(

newJProperty("id",1),

newJProperty("text","test")

));

代码中,只向WriterJObject方法传递了success和data参数,因而,在输出的时候也只会输出这两个属性,与之前代码的输出是一样的。

如果现在重新生成解决方案,并在浏览器打开应用程序,获得的结果与之前的测试是一样的。

现在,还未能充分体现出WriterJObject方法的好处,等阅读完本书后,就可体会到了。

6.4.4统一的错误处理

统一错误处理有什么好处?

好处就是,你不用在调用Ext.Ajax的request方法的时候,再去编写处理错误的代码,也不需要在调用存储的laod方法时候,为他们编写额外的错误处理代码。

总的来说,主要目的就是减少重复代码,便于维护。

要编写统一的错误处理,就要先了解ExtJS框架远程调用的回调机制。

页面处理数据交互的方式主要有Ajax、表单提交和动态加载脚本等三中方式。

在ExtJS经过封装后,基本的数据交互都是采用Ajax方式进行交互的,比较特殊的情况是上传文件时会使用表单方式提交,跨域获取数据采用动态加载脚本的方式。

因而,如果没有特殊情况,在这里就只讨论Ajax这种交互方式。

还要明确的一点是,无论是表单提交(不包括文件上传的表单),还是存储加载数据,最终的交互都是依赖Ajax来实现的,也就是说,统一错误处理要先从最基本的Ext.Ajax入手。

4.Ext.Ajax

使用Ext.Ajax对象时,会有以下3个回调函数:

success、failure和callback。

在这3个回调函数中,callback无论请求是成功还是失败都会触发;而success则在请求的状态码为200到300(不包含300)或304时才会触发;而failure则与success对应使用,不符合success的条件的请求都会触发failure。

选择callback,还是选择success和failure,可以根据自己的习惯来做。

建议的做法是使用success和failure,因为这样可以使用全局统一的错误处理机制来处理failure的结果。

那么,怎么来实现这个全局统一的错误处理机制呢?

一是可以在5.9节中创建的全局变量类中添加方法进行处理,一是创建一个扩展类来处理。

根据面向对象的封装原则,最好的方式当然是创建扩展类的方式。

下面,在Scripts\app\ux\data目录下添加一个名为FailureProcees.js的JavaScript文件,并加入以下定义代码:

Ext.define('SimpleCMS.ux

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 信息与通信

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1