内容


在 Ajax 应用程序中使用 Ext.Direct

使用 PHP 简化客户端和服务器端 Ajax 开发

Comments

简介

Ajax 的概念允许 web 应用程序从一个缓慢的、反应迟钝的、与直觉相反的状态逐渐演化成像桌面应用程序一样,提供即时反馈,消除页面更新需求并促进更好的用户体验。使用 Ajax 的问题是它向应用程序开发过程增加了一个额外的复杂度层。在事件驱动的应用程序中,您可以在用户点击按钮时执行操作。在传统的应用程序开发中,您可以把所有的逻辑(这一操作应该做什么)都放在事件处理程序上,但是有了 Ajax ,似乎就不是那么容易了。您可能需要进行客户端有效验证,如果通过验证,您就可以准备数据并创建一个新 Ajax 请求。然后,您可以定义函数来处理成功和失败响应。接下来,您需要创建服务器端代码来处理 Ajax 请求并返回适当响应。这可能需要在某个数据格式中完成,比如 JavaScript Object Notation (JSON) 或者 XML,而且您必须以客户端期望收到的方式来提供它。

简而言之,Ajax 开发在客户端和服务器端都需要一个 web 应用程序开发人员维护代码集,而两端的工作可能会有巨大的差异,这使得调试和维护很困难。如果能有一种方法,使得开发人员可以在客户端调用服务器端操作、最小程度地减少暴露于所有 Ajax 请求和响应处理,那就太好了。这就是引入 Ext.Direct 的原因。

开始,Ext.Direct 似乎是一个热衷于小问题的解决方案,但是一开始就投入精力和时间,之后您将获得丰厚的回报。获取 Ext.Direct 构建模块最初的障碍似乎很复杂,但是它通常只需要做一次,后来需要添加新类和方法的修改就非常简单了。在本文中,您将了解如何入手将构建模块落实到位,以及如何实际使用 Ext.Direct 从 JavaScript 调用远程 PHP 方法。您将学习一些 Ext.Direct 提供的高级特性,以及如何在您的应用程序中充分的利用这些特性。

先决条件

本文使用 Ext.Direct 实现与 PHP 服务器端脚本通信。如果您的 web 服务器上没有安装 PHP,目前流行的 XAMPP 包可供 Linux®、Windows®、Mac OS X 和 Solaris 使用。参考 参考资料 链接,安装 Apache、PHP、MySQL、以及其他。

要使用 Ext.Direct,您需要下载和解压 ExtJS JavaScript 库,并将其放在您的 web 服务器文件的根目录下。如果用的是 XAMPP,在 XAMPP 安装目录中寻找一个名为 htdocs 的子目录 — 这是您的 Apache 文件目录。在该路径下创建一个名为 direct 的目录。现在,到 sencha.com(见 参考资料)下载 ExtJS 最新的发布版本(写这篇文章时是 3.2.1)。下载之后,将所有文件解压到您刚才建立的目录下。最后一步为路径重命名,将 ext-3.x.x 改为 ext。我在代码示例中使用 ext 作为路径名来防止版本冲突(参阅 下载,访问本文示例源代码)。

开始使用 Ext.Direct

要了解 Ext.Direct 是如何工作的最好方法是立即开始使用。咋一看,这似乎很复杂,但是当您对它有一个基本的了解之后,它的潜在用法和功能都将变得非常清晰。在本小节,您将学习如何创建一个基本的 web 页,在该 web 页中您可以通过 PHP 的 date 功能利用 Ext.Direct 从服务器获取当前日期和时间。

配置文件

如果您想使用 Ext.Direct 将服务器端类的方法公开到 ExtJS,则必须创建一个定义了客户端可用的类和方法的配置文件。这个配置文件可以是您所用的编程语言的一组本地键/值对,也可以是一个 JSON 或 XML 文件。本例中使用 PHP 阵列避免了解析 JSON 或 XML。打开您常用的本文编辑器,将清单 1 中的代码添加到其中,将其命名为 config.php 并保存在之前创建的 direct 目录下。

清单 1. config.php — Ext.Direct 类和方法的 PHP 配置文件
<?php
$API = array(
    'Now'=>array(
        'methods'=>array(
            'getNow'=>array(
                'len'=>0
            )
        )
    )
);

清单 1 中的代码定义了 API。最外层数组只包含一个键/值对,键名是 Now。这是您想要公开的 PHP 类的名称,由一个数组 Now 构成,该数组也只含有一个成员 methods,指出它包含了您将要在 Now 类中公开的方法。在 methods 数组中有一个成员 getNow,指的是您将要公开的方法 getNow()。它本身也是一个数组,定义了 len 属性,该属性指出 getNow() 函数接收的变量的个数。在这个案例中,您不需要传递任何参数,因此其值为 0。

PHP 类

接下来,我们来看对应的 PHP 文件,在 direct 下创建一个新目录,并将其命名为 classes。在此目录下,创建一个新文件,命名为 Now.php,然后将清单 2 的内容添加到其中。

清单 2. classes/Now.php — 您将要从 Ext.Direct 调用的 PHP 类
<?php
class Now {
    function getNow() {
        return date('jS F Y @ g:i:s a');
    }
}

如您所见,该类的名字为 Now,与您在 config.php 中声明的类名相对应。该类有一个方法 getNow(),不接受参数。getNow() 函数以 27th August 2010 @ 12:21:34 pm 这种格式返回当前时间。

下一个您需要放置到位的模块是,向 Ext.Direct 公开可用方法的 JavaScript API。您可以使用 PHP 编写这个 API,加载 config.php 文件内容,生成一个 Ext.Direct 能够阅读和理解的 JSON 版本。这个 API 是通用的,如果您想添加更多的类或方法,不需要对其进行修改。稍后您将看到 API 是如何加载到 web 页面的。

API

创建一个新文件 api.php,将清单 3 的代码复制到其中。

清单 3. api.php — 您的 PHP 类和方法的动态 JavaScript API
<?php
require('config.php');
header('Content-Type: text/javascript');

$actions = array();
foreach($API as $aname=>&$a){
    $methods = array();
    foreach($a['methods'] as $mname=>&$m){
        $md = array(
            'name'=>$mname,
            'len'=>$m['len']
        );
        if(isset($m['formHandler']) && $m['formHandler']){
            $md['formHandler'] = true;
        }
        $methods[] = $md;
    }
    $actions[$aname] = $methods;
}

$cfg = array(
    'url'=>'router.php',
    'type'=>'remoting',
    'actions'=>$actions
);
echo 'Ext.app.REMOTING_API = ';

echo json_encode($cfg);
echo ';';

该脚本首先加载 config.php 文件,指定 web 浏览器内容的输出类型为 JavaScriptfile。实际上,您可以使用一个 <script> 标签将这个文件加载到您的 HTML 页面,以后输出都是 JavaScript。config.php 文件声明一个变量 $API,其中包含带有 Ext.Direct 将要用到的类和方法的键/值对。清单 3 中的脚本根据这些类和方法的名称使用 JavaScript 扫描 $API 变量,来定义可用操作。然后创建一个 $cfg 键/值数组,来定义发送程序(马上将创建)的 URL、类型(被设置为 remoting)和操作变量。最后,JavaScript 被输出,用为 $cfg 变量的 JSON 呈现设置的值定义 Ext.app.REMOTING_API。稍后,您将看到实际上浏览器从该文件读取的内容。

发送程序

在您真正使用 Ext.Direct 来调用服务器端方法之前,最后一个您需要落实到位的是发送程序。麻烦的是,将客户端的请求转移到服务器端并将其发送到请求的类。然后调用适当的方法、传递该方法的相关参数。发送程序必须处理两种格式的请求 — JSON 编码的原始 HTTP post(用于检索数据)和表单 post(用于更新数据)。如果多个请求同时发出,HTTP 将发送一个数组,发送程序将需要为每个请求选择合适的路径发送。

要创建发送程序,需要创建一个新文件,命名为 router.php,保存在 direct 文件夹。其内容如清单 4 中的代码。

清单 4. router.php — PHP 脚本,发送请求到合适的 PHP 类
<?php
require('config.php');

class ExtAction {
    public $action;
    public $method;
    public $data;
    public $tid;
}

$isForm = false;
$isUpload = false;
if(isset($HTTP_RAW_POST_DATA)) {
    header('Content-Type: text/javascript');
    $data = json_decode($HTTP_RAW_POST_DATA);
} else if(isset($_POST['extAction'])) {
    $isForm = true;
    $isUpload = $_POST['extUpload'] == 'true';
    $data = new ExtAction();
    $data->action = $_POST['extAction'];
    $data->method = $_POST['extMethod'];
    $data->tid = isset($_POST['extTID']) ? $_POST['extTID'] : null;    
    $data->data = array($_POST, $_FILES);
} else {
    die('Invalid request.');
}

function doRpc($cdata){
    global $API;
    try {
        if(!isset($API[$cdata->action])) {
            throw new Exception('Call to undefined action: ' . $cdata->action);
        }
        $action = $cdata->action;
        $a = $API[$action];

        doAroundCalls($a['before'], $cdata);

        $method = $cdata->method;
        $mdef = $a['methods'][$method];
        if(!$mdef){
            throw new Exception("Call to undefined method: $method on action $action");
        }
        doAroundCalls($mdef['before'], $cdata);

        $r = array(
            'type'=>'rpc',
            'tid'=>$cdata->tid,
            'action'=>$action,
            'method'=>$method
        );

        require_once("classes/$action.php");
        $o = new $action();

        $params = isset($cdata->data) && is_array($cdata->data) ? 
                                             $cdata->data : array();

        $r['result'] = call_user_func_array(array($o, $method), $params);

        doAroundCalls($mdef['after'], $cdata, $r);
        doAroundCalls($a['after'], $cdata, $r);
    } catch(Exception $e) {
        $r['type'] = 'exception';
        $r['message'] = $e->getMessage();
        $r['where'] = $e->getTraceAsString();
    }
    return $r;
}

function doAroundCalls(&$fns, &$cdata, &$returnData=null) {
    if(!$fns) {
        return;
    }
    if(is_array($fns)) {
        foreach($fns as $f) {
            $f($cdata, $returnData);
        }
    } else {
        $fns($cdata, $returnData);
    }
}

$response = null;
if(is_array($data)) {
    $response = array();
    foreach($data as $d) {
        $response[] = doRpc($d);
    }
} else {
    $response = doRpc($data);
}
if($isForm && $isUpload) {
    echo '<html><body><textarea>';
    echo json_encode($response);
    echo '</textarea></body></html>';
} else {
    echo json_encode($response);
}

发送程序的代码相当多,但是和 API 一样,它是通用代码,如果您想要将其添加到 Ext.Direct 可执行的任何新方法或类中,无需任何修改。在文件的开始,一个基础类定义了 4 个属性。如果请求是表单 post 形式的,该类将被使用。接下来,检查请求是否包含原始 HTTP post 数据;如果有,返回一个 JSON 编码的响应。否则,实例化 ExtAction 类,并以表单 post 数据为属性赋值。

接下来,有一个名为 doRpc 的函数,找出 Ext.Direct 应该调用的类和方法并加载有关类,调用适当的方法为其传递提供的任何变量值。doAroundCalls 方法将调用任何被设置为操作前或操作后调用的方法。在这个例子中您用不到它,因此目前您不需要关注太多。

文件的末尾,您建立了一个响应。如果有多个响应,通过请求数组循环,为每一个调用 doRpc 函数。如果只有一个简单的请求,只需要调用 doRpc 一次。最后,查看请求是一个表单 post 还是文件上传,在这种情况下,输出数据作为一个有效的 HTML 页面,该页面的 <textarea> 元素中含有 JSON 格式编码的输出。这是一个响应表单 post 请求的 Ext.Direct 规范的需求。如果是请求一个原始的 HTTP post,只需要分配一个 JSON 编码的响应(之前为了使用 MINE 类型 text/javascript,您已经为响应定义了头部)。

使用 JavaScript 调用远程方法

有了这些配置、PHP 类 API 和已创建的所有发送程序,您现在在 Now PHP 类中可以使用 Ext.Direct 调用 getNow() 了。在您的 direct 文件夹中创建一个名为 first.php 的新文件,并将清单 5 中的代码添加到其中。

清单 5. first.php — 您的第一个 Ext.Direct 应用程序
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Ext.Direct Server Date/Time</title>
    <link rel="stylesheet" href="ext/resources/css/ext-all.css" />
    <script src="ext/adapter/ext/ext-base.js"></script>
    <script src="ext/ext-all.js"></script>
    <script src="api.php"></script>
</head>
<body>
<h1>Ext.Direct Server Date/Time</h1>
<script>
    Ext.onReady(function(){
        Ext.Direct.addProvider(Ext.app.REMOTING_API);

        Now.getNow(function(provider, response) {
            alert(response.result);
        });
    });
</script>
</body>
</html>

清单 5 是一个比较简单的 HTML 文件。您只需要在您的 <head> 标签中包含常规 ExtJS 文件(ext-all.css、ext-base.js 和 ext-all.js)以及您之前创建的可远程访问的 API(api.php)。然后,您需要编写一些会将您的 API 作为一个 Ext.Direct 提供者添加的 JavaScript 代码,这将创建相关 JavaScript 类和方法,这些类和方法允许您调用服务器端 PHP 方法。接下来,从 Now 类调用您的服务器端方法 getNow。Ext.Direct 调用用一个函数作为参数,它本身接受两个参数:providerresponseresponse 包含您从服务器端 PHP 脚本收到的响应。

运行项目

现在,您已经创建了您的第一个 Ext.Direct 应用程序所需的全部代码了,让我们来运行项目,查看其生成结果。打开您常用的 Web 浏览器,链接到 http://127.0.0.1:5984/direct/first.php。弹出一个提示消息,其中显示当前的日期和时间,因为这是在服务器端生成并格式化的。窗口如图 1 所示。

图 1. 运行中的第一个 Ext.Direct 应用程序
屏幕显示 2010 年 8 月 27,4:30 pm 和一个 OK 按钮。
屏幕显示 2010 年 8 月 27,4:30 pm 和一个 OK 按钮。

如果您使用的是 Firefox 这类浏览器,可以点击链接,进入您 View Source 视图中的外部 JavaScript 文件,在弹出的警告对话框中单击 OK 关闭该消息,然后在页面上任何位置单击右键,接着点击 View Source。寻找下面这行:<script src="api.php">

这一行的 api.php 部分是一个可点击的链接。点击该链接可以链接到 api.php 的 JavaScript 源,在 config.php 中定义的类和方法。源中应该包含以下内容:Ext.app.REMOTING_API = {"url":"router.php","type":"remoting","actions":{"Now":[{"name":"getNow","len":0}]}};

这声明了 Ext.app.REMOTING_API 配置,当您在您的代码中试着使用公开的方法时,您可以将其作为您的提供者使用。

继续下一步之前,我们来探讨一下,如果想添加 Ext.Direct 可以有效使用的新类和新方法时,还需要什么。在本例中,让我们创建一个名为 Server 的类,在该类中创建一个名为 getSoftware 的方法。这将反馈 web 服务器和 PHP 安装的详细情况。首先,创建一个新的名为 Server.php 的文件,并将其保存在 direct 目录(与 Now.php 文件一起)中的 classes 子目录下。其内容如清单 6 所示。

清单 6. classes/Server.php — 第二个类
<?php
class Server {
    function getSoftware() {
        return $_SERVER['SERVER_SOFTWARE'];
    }
}

getSoftware 方法只返回环境变量 SERVER_SOFTWARE 的值。接下来,您需要修改 config.php 来告知 Ext.Direct 这个新方法可用于远程调用。修改 config.php,其内容如清单 7 所示。

清单 7. 更新 config.php — 引用新类和新方法
<?php
$API = array(
    'Now'=>array(
        'methods'=>array(
            'getNow'=>array(
                'len'=>0
            )
        )
    ),
    'Server'=>array(
        'methods'=>array(
    	      'getSoftware'=>array(
                'len'=>0
    	      )
        )
    )
);

如您所见,您只需要向 Server 类中添加引用,您已经定义了,它包含一个方法 getSoftware,该方法不接受参数。您需要进行的最后一个修改是针对您的第一个 frist.php 文件的,您实际上是在其中执行了对服务器端方法的调用。在本例中,您只需要在第二个警告对话框中显示从 Server.getSoftware() 方法传回的响应。在您的第一个 frist.php 文件中 Now.getNow 的结束符号 }); 之下,添加以下代码(清单 8)。

清单 8. Now.getNow 调用
Server.getSoftware(function(provider, response) {
    alert(response.result);
});

现在,返回到您的浏览器并刷新页面。您将看到与第一个弹出对话框相似的日期值。关闭消息时,您将看到第二个警告对话框,这次显示的是服务器端软件信息,如图 2 所示。

图 2. 从您最新添加的方法传回的响应
窗口显示一个 Apache 消息和一个 OK 按钮。
窗口显示一个 Apache 消息和一个 OK 按钮。

奠定了这些基础之后,我认为您将会赞同添加新类和方法的过程相对比较简单这种说法。最后,检查 api.php 生成的 JavaScript 代码,其中应该包含清单 9 所示内容。

清单 9. api.php 产生的 JavaScript 代码
Ext.app.REMOTING_API =
 {"url":"router.php","type":"remoting","actions":{"Now":[{"name":"getNow",
 "len":0}],"Server":[{"name":"getSoftware","len":0}]}};

如您所见,现在已经包含了 Server 类和 getSoftware 方法了,然后它们被用来在 JavaScript 中执行这些功能了。

以上所述已经涵盖了 Ext.Direct 工作的基础。在下一部分中,您将学习一些更高级的 Ext.Direct 概念,包括接受参数的方法、返回更复杂的响应和在请求中发送表单数据而不是以原始的 HTTP post 数据。然后,准备将您在本文中所学到的应用于您自己的应用程序。

下一步:更复杂的 Ext.Direct 概念

在上一部分,您已经学习了 Ext.Direct 开发的基础知识。然而,在您准备将自己所学的知识用于构建自己的应用程序之前,还有一些其他的概念,您应该了解,这一部分将介绍这些概念。

在您的方法中接受参数

在上一部分,您公开到 Ext.Direct 的两个方法都是非常基础的,甚至不能接受参数。将参数传递到您创建的服务器端函数,这是很有可能的,所以,让我们来看看,如何改写一个函数来接受和使用参数。

首先,打开您之前创建的 config.php 文件,然后在 getNow 方法引用中将 len 属性值从 0 修改到 1。这将告知 Ext.Direct,getNow 方法希望接受一个参数。

接下来,您需要修改 Now.php 类,将该文件内容更改为清单 10 所示的代码。

清单 10. 修改后的 classes/Now.php
<?php
class Now {
    function getNow($format) {
        return date($format);
    }
}

您将会看到函数 getNow 现在可以接受一个参数 $format 了,这个参数被嵌入到 PHP date() 函数的调用中。

最后一步是修改 first.php 文件,当调用 remote 方法时,可以接受一个参数,寻找清单 11 中的这一行。

清单 11. 修改 first.php 文件
Now.getNow(function(provider, response) {
    alert(response.result);
});

要想在该方法的调用中传递一个参数,在如下所示的 callback 函数之前放置一个参数(见清单 12)。

清单 12. 在 callback 函数之前放置参数
Now.getNow('jS F Y', function(provider, response) {
    alert(response.result);
});

接着,重新加载浏览器窗口,查看修改。这时,getNow 方法调用的响应只返回日期,而不是日期和时间,如图 3 所示。

图 3. 在参数中指定日期格式的结果
屏幕显示 2010 年 8 月 29 和一个 OK 按钮
屏幕显示 2010 年 8 月 29 和一个 OK 按钮

接下来,您将看到,比起单一值来更复杂的结果是如何返回的。

返回复杂的结果集

直到现在,您的方法生成的响应都只是一个单一的数值。这对于基本功能已经很不错了,但是在实际中,您可能需要返回更复杂的类型,比如对象和数组。因为您返回的响应是 JSON 格式的,这非常明确。您的 PHP 类方法可以返回数组或者键/值对,您定义的 API 将从其中自动生成一个 JSON 数组或对象。让我们来看一个简单的示例。首先,您需要修改您的 Server 类,因此,打开 classes/Server.php 文件,添加清单 13 所示的函数。

清单 13. 将 getEnvVars() 函数添加到 Server
function getEnvVars() {
    return $_SERVER;
}

现在,修改 config.php 文件来包含这个新方法,文件的内容现在应当镜像清单 14 中所示的代码。

清单 14. 修改后的 config.php — 添加新 getEnvVars 方法
<?php
$API = array(
    'Now'=>array(
        'methods'=>array(
            'getNow'=>array(
                'len'=>1
            )
        )
    ),
    'Server'=>array(
        'methods'=>array(
    	      'getSoftware'=>array(
                'len'=>0
            ),
            'getEnvVars'=>array(
                'len'=>0
            )
        )
    )
);

接下来,在您的 direct 文件夹中创建一个名为 second.php 的新文件。您将使用它作为一个新 web 页来调用您最新创建的 getEnvVars 方法。将清单 15 的内容添加到其中,然后保存。

清单 15. second.php — 使用新 getEnvVars 方法
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Ext.Direct Complex Responses</title>
    <link rel="stylesheet" href="ext/resources/css/ext-all.css" />
    <script src="ext/adapter/ext/ext-base.js"></script>
    <script src="ext/ext-all.js"></script>
    <script src="api.php"></script>
</head>
<body>
<h1>Ext.Direct Complex Responses</h1>
<script>
    Ext.onReady(function(){
        Ext.Direct.addProvider(Ext.app.REMOTING_API);

        Server.getEnvVars(function(provider, response) {
            alert(response.result.DOCUMENT_ROOT);
            alert(response.result.HTTP_USER_AGENT);
            alert(response.result.MYSQL_HOME);
        });
    });
</script>
</body>
</html>

现在,打开您的浏览器,链接到 http://127.0.0.1/direct/second.php。您将看到 3 个弹出对话框,分别显示您 web 服务器的文件根目录的位置、您使用的浏览器的用户代理字符串、以及您系统上 MySQL 的安装位置(如果有)。

发送表单 post 数据

在本节中,您将学习如何从一个表单发送数据到服务器,是以表单 post 请求而不是原始的 HTTP post 发送。您将创建一个简单的表单,只有一个字段 Enter a number 和一个 Validate 文本按钮。目的是将字段在服务器端验证,检查其是否为空,其值是否是整数。如果验证失败,您需要向用户显示一条错误消息。当然,您可以通过基本 JavaScript 来完成这个任务,但在真实应用程序中,您可以轻松调整这个概念来针对数据库验证输入,例如检查是否接受了一个请求的用户名。

在本例中,您将创建一个新 PHP 类 NumberValidator,该类只有一个方法 validateNumber。第一步将这个新类和方法添加到 config.php 文件。大部分和前面一样,但是您必须指定,该方法使用一个表单处理程序而不是原始的 post 处理程序,修改 config.php 文件,使其和清单 16 中的代码匹配。

清单 16. 修改后的 config.php — 添加 NumberValidator
<?php
$API = array(
    'Now'=>array(
        'methods'=>array(
            'getNow'=>array(
                'len'=>1
            )
        )
    ),
    'Server'=>array(
    	'methods'=>array(
    		'getSoftware'=>array(
    		    'len'=>0
    		),
    		'getEnvVars'=>array(
    		    'len'=>0
    		)
    	)
    ),
    'NumberValidator'=>array(
        'methods'=>array(
            'validateNumber'=>array(
                'len'=>1,
                'formHandler'=>true
            )
        )
    )
);

接下来,您需要创建类。创建一个新文件,然后将其在 classes 子目录下保存为 NumberValidator.php,其内容如清单 17 所示。

清单 17. classes/NumberValidator.php — 新验证类
<?php
class NumberValidator {
    function validateNumber($form) {
        $response = array();
        $num = $form['num'];
        if (strlen($num) < 1) {
            $success = false;
            $response['errors'] = array(
                'num'=>'Required field.'
            );
        } else if (!is_numeric($num)) {
            $success = false;
            $response['errors'] = array(
                'num'=>'Not a valid number.'
            );
        } else {
            $success = true;
        }
        $response['success'] = $success;
        return $response;
    }}

这个类相对简单。提交表单中的值将被作为一个参数接收。您将创建一个名为 num 的字段,您需要验证这个字段。您要检查这个字段是否没有任何值或者不是数字的,以及如果出现这两种情况中的一种,您应该返回一个错误。如果个数验证为真,此方法返回一个对象 $response,该对象有一个成员 success,其值为真;否则将返回两个成员,其值为 false 的 success 和一个 error 对象,错误相关消息在字段中显示。

最后一步是用代码创建一个新 web 页面,来创建表单并处理 Validate 按钮上的提交事件。毕竟这是一个 ExtJS 教程,让我们在流程中使用一些 ExtJS UI 构件。创建一个名为 third.php 的新文件,然后保存在您的 direct 目录下。将清单 18 的内容添加到该文件。

清单 18. third.php — 最后一个示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
    <title>Ext.Direct Form Example</title>
    <link rel="stylesheet" href="ext/resources/css/ext-all.css" />
    <script src="ext/adapter/ext/ext-base.js"></script>
    <script src="ext/ext-all.js"></script>
    <script src="api.php"></script>
</head>
<body>
<h1>Ext.Direct Form Example</h1>
<script>
    Ext.onReady(function(){
        Ext.Direct.addProvider(Ext.app.REMOTING_API);

        Ext.QuickTips.init();

        var formExample = new Ext.form.FormPanel({
            title: 'Validation Form',
            padding: 10,
            buttons:[{
                text: 'Validate',
                handler: function(){
                    formExample.getForm().submit();
                }
            }],
            renderTo: Ext.getBody(),
            defaultType: 'textfield',
            items: [{
                fieldLabel: 'Enter a number',
                name: 'num',
                msgTarget: 'side'
            }],
            api: {
                submit: NumberValidator.validateNumber
            }
        });
    });
</script>
</body>
</html>

如果您对 ExtJS 已经很熟悉了,您应该能看明白这些代码。如果您之前没有使用过 ExtJS,这些代码可以创建一个新的 FormPanel(ExtJS 的许多优秀 UI 控件之一),有一个带有文本 Validate 的按钮。按钮的事件处理程序,在点击按钮时表单将被提交。这个代码指出表单应提交给执行代码的网页的文档主体。这些代码将添加到页面的底部(本例中,是在 <h1> 元素之下)。接着,代码定义了应该在表单中出现的条目,在本例中,只有一条 num 字段。最后,提交 API 被指定。在本例中,您使用 NumberValidator.validateNumber Ext.Direct 方法,只要表单被提交(Validate 按钮被点击),它将随后被调用。

所有代码都已创建,打开您的浏览器,链接到 http://127.0.0.1/direct/third.php。您将看到一个漂亮的表单,有一个字段和一个 Validate 按钮。首先将字段清空,然后单击按钮。字段应该是用红色突出显示的,旁边有一个图标,如图 4 所示。将鼠标移动到图标上方,您将看到消息 Required field

图 4. 运行中的表单示例
屏幕上显示输入一个数字,字段轮廓呈红色。
屏幕上显示输入一个数字,字段轮廓呈红色。

接下来,输入一个有效数字并点击 Validate。您将注意到,字段不再突出显示,图标也消失了。最后输入一个无效数字,比如文本文字 test,再次单击 Validate,字段再次突出显示,图标提示框将出现消息 Not a valid number

结束语

本文是 Ext.Direct 的一个高级介绍,向您展示了使用它的基础知识。首先,您学习了什么是 Ext.Direct,以及它主要解决什么问题,也就是配置、API、发送程序、PHP 类和使用 Ext.Direct 的应用程序文件。在这一过程中,您学习了在您的应用程序中如何调用 Ext.Direct 方法。然后您学习了如何传递参数到您的服务器端方法,以及如何从服务器中返回更复杂的数据。最后,您学习了如何处理表单数据,提供基于表单输入的服务器端验证。

还有更多 Ext.Direct 的探讨 — 查阅 参考资料,链接这一主题的其他文章和指南。目前,Ext.Direct 是一个新兴技术,您应期盼它不断发展,随着时间的推移逐渐功能丰富。现在,您已经学习了基础知识,那么将来您就有了使用所有 Ext.Direct 强大功能的基础了。


下载资源


相关主题


评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Web development, Open source
ArticleID=764569
ArticleTitle=在 Ajax 应用程序中使用 Ext.Direct
publish-date=10102011