Ext3.X新特性:简介如何在.NET中使用Ext.Direct

 

Ext3.X新特性:简介如何在.NET中使用Ext.Direct

                                           张铭诺

Ext3.X 增加了Ext.Direct对象,其最大的好处就是实现服务器端平台和语言的跨平台性,只要定义好服务器端的对象及方法,无论服务器端使用什么平台或语言,客户端根据服务端的对象与方法,都可以从服务器获取需要的数据。其工作原理就是将服务端的对象及其方法映射到客户端,客户端经过路由器的转换就可以实现直接访问这些对象及其方法。

Ext.Direct的路由器(Router)还在完善当中,目前针对.NET的是1.0版,大家可以到http://extjs.com/dorum/showthread.php?t=68161下载。本文的介绍也是基于这个最新的版本。

一、路由器包的内容简介

将下载到本地的“Router-1.0.zip”解压后,生成”Ext.Direct”和“ExtDirectSample”两个目录。“Ext.Direct”目录里是生成类库“Ext.Direct.dll”的项目源文件,而目录“ExtDirectSample”是使用Ext.Direct的一个例子。

下面我们重点介绍“ExtDirectSample”,希望通过分析“ExtDirectSample”可以让大家了解Ext.Direct的运作过程以及如何在.Net中使用Ext.Direct.

我们用VS2008打开“ExtDirectSample”项目的解决方案。发现该项目包含“Echo”、“Form”、“Grid”和“Tree”等多个主题的实例。下面我们从介绍“Echo”文件夹下的几个实例开始。

首先打开“SimpleEcho.aspx”文件,发现在<Head>标签中,引入了以下文件。

 <script type="text/javascript" src="EchoHandler.ashx"></script>

 <script type="text/javascript" src="SimpleEcho.js"></script>

 

其中“SimpleEcho.js”文件是定义页面的内容。而“EchoHandler.ashx”是映射服务器端对象到客户端的。现在我们在Firefox中打开“SimpleEcho.aspx”文件,通过Firebug(Firebug是一款调试脚本的利器,本文篇幅有限,在此不作详述,其具体用法请读者自行查阅资料)查看“EchoHandler.ashx”到底返回了什么内容。打开Firebug后,切换到“网络”标签页,然后展开“EchoHandler.ashx”并切换到“响应”标签页,将看到图一所示内容。

图一

从图一中可以看到,“EchoHandler.ashx”返回的是一个对象,对象中包含了访问地址以及服务器端的对象及其方法名称。

为了了解这些结果是怎么返回的,我们再回过头来研究一下“EchoHandler.ashx”的源文件,其部分源代码如下所示:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using Ext.Direct;

namespace ExtDirectSample.Echo

{

    [DirectAction("Echo")]

    public class EchoHandler : DirectHandler

    {

        public override string ProviderName

        {

            get

            {

                return "Sample.Remote.EchoHandler";

            }

        }

        public override string Namespace

        {

            get

            {

                return "Sample";

            }

        }

        [DirectMethod]

        public string GetGreeting()

        {

            return "Hello World!";

        }

   

         }

}

在代码中,我们可以看到引用了Ext.Direct库,而且EchoHandler类是继承自DirectHandler类的。在EchoHandler类上还定义了“DirectAction”属性,表示该类需要Ext.Direct对象将其映射到客户端。同理,“DirectMethod”属性表示该方法需要Ext.Direct对象将其映射到客户端。

在EchoHandler类上还定义了ProviderName和Namespace两个属性,与图一中显示的内容对比一下属性定义的字符串,可以知道,ProviderName属性定义的是返回客户端的对象名,而Namespace则是对象中的命名管道。

我们再打开"SimpleEcho.js",看看在客户端究竟是怎么使用这些映射到客户端的对象及其方法的,其源代码清单如下所示。

Ext.Direct.addProvider(Sample.Remote.EchoHandler);

Ext.onReady(function(){

    var panel = new Ext.Panel({

        renderTo: 'container',

        width: 200,

        height: 200,

        bodyStyle: 'padding: 5px;',

        title: 'Simple Echo',

        tools: [{

            id: 'refresh',

            handler: function(){

                Sample.Echo.GetGreeting(function(data, trans){

                    panel.body.update(data);

                });

            }

        }]

    });

});

"SimpleEcho.js"开头就定义执行一下语句:

“Ext.Direct.addProvider(Sample.Remote.EchoHandler);”

其作用是在Ext中注册对象,如果没有注册,则映射的对象是不能使用的。

大家可能注意到了,addProvider方法中的参数名称就是在ashx文件中定义的ProviderName属性。

然后就可以在程序中通过在ashx文件中的Namespace属性定义的命名管道来访问对象和方法,例如以下代码:

Sample.Echo.GetGreeting(function(data, trans){

                    panel.body.update(data);

 });

代码中“Sample”就是在ashx文件中定义的Namespace属性值。

我们再看看方法参数是如何传递的,先看看DirectMethod属性定义的方法。在“EchoHandler.ashx”中,使用DirectMethod属性定义的带参数的方法有以下两个,下面我们只看Sum方法:

        [DirectMethod]

        public long Sum(long a, long b)

        {

            return a + b;

        }

而客户端调用对应的脚本代码如下所示:

 Sample.Echo.Sum(a, b, function(data, trans){

                    // clear anything from the previous request

                    form.remove('label');

                    form.add({

                        itemId: 'label',

                        xtype: 'label',

                        html: String.format('{0} + {1} = <b>{2}</b>', a, b, data)

                    });

                    form.doLayout();

                    form.getComponent('label').getEl().highlight();

                });               

从代码中可以看出,使用DirectMethod方式定义的带有参数的方法,在调用脚本中只要直接在回调函数前加入对应的参数即可。

下面我们再介绍一下用DirectMethodForm属性定义的方法。打开Form目录下的“FormHandler.ashx”文件,发现在该文件中,Upload方法和Save方法使用了该属性,下面只介绍Save方法,代码如下:

 [DirectMethodForm]

        public JObject Save(HttpRequest request)

        {

            JObject data = new JObject(

                new JProperty("company", this.ParseString(request["company"])),

                new JProperty("firstName", this.ParseString(request["firstName"])),

                new JProperty("lastName", this.ParseString(request["lastName"])),

                new JProperty("email", this.ParseString(request["email"])),

                new JProperty("expires", this.ParseDate(request["expires"])),

                new JProperty("maxEmails", this.ParseNumber(request["maxEmails"])),

                new JProperty("receiveEmail", this.ParseBoolean(request["receiveEmail"]))

            );

            return new JObject(

                new JProperty("success", true),

                new JProperty("data", data)

            );

        }

因为是form提交,参数的数量是不确定的,所以在方法中只提供了一个参数,返回HttpRequest对象,让开发人员自己提取提交参数。因而在客户端调用也不用考虑参数问题,只定义好API,提交到那个方法就行了,如以下代码所示:

api: {

            submit: Sample.Form.Upload

        },

现在在Firefox中打开Form.aspx文件,单击“Load”按钮,在“Simple Form”中,将“First Name”修改为“Evan001”,然后单击“Save”按钮,可分别在FireBug中的Post标签页和响应标签页看到以下结果:

//Post结果

company        Ext

email           evan@extjs.com

expires          2010-10-03

extAction        Form

extMethod       Save

extTID          3

extType         rpc

extUpload       false

firstName        Evan001

lastName        Trimboli

maxEmails       4

receiveEmail      on

//响应结果

[{"type":"rpc","tid":3,"action":"Form","method":"Save","result":{"success":true,"data":{"company":"Ext","firstName":"Evan001","lastName":"Trimboli","email":"evan@extjs.com","expires":new Date(1286035200000),"maxEmails":4,"receiveEmail":true}}}]

从以上结果可以看出,提交的信息主要包括action、method、data、type、tid五个部分,其中action表示对象名,method是调用的方法,data内包含的是提交数据,type表示访问类型,tid是一个计数器。Form的提交特别一点,不过也是包含这五部分的,但在其名称前加了ext这个前缀。为了避免混淆,我们在定义form内控件的名字时要注意了,不要与这5个特定提交参数名称相同。

我们再比较一下返回结果,其结构也是固定的,与post的信息一样,也由5个部分组成,不过data部分变成了result,在这里包含的是方法返回的结果。

通过以上学习,我们可以总结出在.Net中使用Ext.Direct必须注意以下几点:

l         在ASHX文件中定义对象及其方法。

l         对象必须继承自DirectHandle。

l         在定义对象及其方法时,要在映射的对象及其方法中加入DirectAction、DirectMethod或DirectMethodForm属性。其中DirectAction用于定义对象,DirectMethodForm用于定义Form提交的方法,并注意Form提交只有一个接收参数,为HttpRequest对象。

l         需要在对象中定义ProviderName属性。为了方便客户端调用,最好附加定义Namespace属性。

l         在客户端需要使用addProvider方法注册对象,其语法格式为:Ext.Direct.addProvider(ProviderName);其中,ProviderName为ASHX定义的ProviderName属性值。

l         客户端一般调用方法格式为:Namespace.Object.method(arg1,arg2,…,callback);其中,Namespace为ASHX文件定义的Namespace属性值;Object为对象名;method为方法名称;arg1,arg2为参数;callback为回调函数。

l         如果是form,定义其API属性即可。

l         服务器端的返回结果在返回的数据结构的result属性里。

二、DIY一个Ext.Direct实例

通过上面的介绍,我们对如何在.NET中使用Ext.Direct有了一定了解,现在我们可以尝试DIY一个例子来实践一下。

需求分析:

例子要实现的功能很简单,在页面中放入一个按钮,单击该按钮后从服务器段获取字符串“Hello”,然后使用Ext提示窗口显示出来。

解决方法:

步骤一:基本环境配置。

在VS2008中新建一个网站“MyFirstSample”,在右边“解决方案资源管理器”的根节点上点击鼠标右键,从“添加ASP.NET文件夹”菜单中选择“bin”子菜单。然后将Ext.Direct.dll和Newtonsoft.Json.dll两个文件添加到bin目录里。Ext.Direct.dll是Ext.Direct的对象库,使用Ext.Direct必须引用它。Newtonsoft.Json.dll则是在.Net中处理JSON数据用的,这也是Ext.Direct对象中需要引用的。

新建一个名称为“ext”的目录,将必须的Ext资源文件复制到该目录。

步骤二:建立服务器端一般处理程序。

在“解决方案资源管理器”中右键单击,选择“添加新项”,在弹出窗口中选择“一般处理程序”,将文件名修改为“testHandle.ashx”后,单击“添加”按钮。

在引用中增加以下语句:

using Ext.Direct;

在类定义前增加以下语句:

[DirectAction]

将“IHttpHandler”修改为“DirectHandler”后,将类内原有的内容全部消除,然后增加以下代码:

 public override string ProviderName

    {

        get { return "Ext.app.REMOTING_API"; }

    }

    public override string Namespace

    {

        get

        {

            return "MyApp";

        }

    }

    [DirectMethod]

    public string SayHello()

    {

        return "Hello";

    }

    [DirectMethod]

    public string SayHello2(string username)

    {

        return "Hello,"+username;

    }

步骤三:建立展示页面和客户端脚本。

打开Default.aspx页面,在head内加入以下代码:

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

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

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

<script src="testHandle.ashx" type="text/javascript"></script>

以上代码主要是链接Ext库和样式的,testHandle.ashx是服务器端的一般处理程序。

在body内加入以下代码:

<input type="button" value="Hello" id="btnHello" /><br />

   <input type="button" value="Hello2" id="btnHello2" />

   <script type="text/javascript">

       Ext.Direct.addProvider(Ext.app.REMOTING_API);

       Ext.onReady(function() {

           Ext.fly('btnHello').on('click', function() {

               MyApp.testHandle.SayHello(function(data, trans) {

                   Ext.Msg.alert('信息', data);

               });

           });

          Ext.fly('btnHello2').on('click', function() {

           MyApp.testHandle.SayHello2('小张',function(data, trans) {

               Ext.Msg.alert('信息', data);

           });

           });

       });

   </script>

该段代码在页面中加入了两个按钮,id分别为:btnHello和btnHello2。在<script>

下第一句注册Ext.Direct对象。在onReady中为两个按钮增加了单击事件。btnHello按钮单击后将执行服务器端text对象的SayHello方法,然后将返回值使用提示窗口显示出来。btnHello2按钮的单击事件与之类似,值得注意的是,btnHello2执行的SayHello2方法是带有参数的方法。

展示结果:查看页面效果。

这样一个简单的例子就做好了。在浏览器中打开Default.aspx,单击“Hello”按钮,看到如图二所示的结果,单击“Hello2”按钮,将看到如图三所示的结果。

图二

图三

 

 

 

 

posted on 2011-01-30 13:49  言若  阅读(1523)  评论(0编辑  收藏  举报

导航