文档帮助

术语、图标和标签

许多类在使用配置对象创建(实例化)类时都有快捷名称。快捷名称被称为 别名(如果类扩展了 Ext.Component,则为 xtype)。别名/xtype 列在适用类的类名旁边,以便快速参考。

访问级别

框架类或其成员可以指定为 privateprotected。否则,类/成员为 publicPublicprotectedprivate 是访问描述符,用于传达应如何以及何时使用类或类成员。

成员类型

成员语法

下面是一个示例类成员,我们可以对其进行剖析,以展示类成员的语法(在本例中是从 Ext.button.Button 类中查看的 lookupComponent 方法)。

lookupComponent ( item ) : Ext.Component
受保护的

当原始配置对象添加到此容器时调用,无论是在 items 配置的初始化期间,还是在 添加新项目或 {@link #insert 插入} 时。

此方法将传递的对象转换为实例化的子组件。

当需要对子组件创建应用特殊处理时,可以在子类中覆盖此方法。

参数

item :  Object

正在添加的配置对象。

返回值
Ext.Component

要添加的组件。

让我们看一下成员行的每个部分

成员标志

API 文档使用许多标志来进一步传达类成员的功能和意图。标签可以用文本标签、缩写或图标表示。

类图标

- 表示框架类

- Singleton 框架类。*有关更多信息,请参阅 singleton 标志

- 组件类型框架类(Ext JS 框架中扩展 Ext.Component 的任何类)

- 表示类、成员或指南在当前查看的版本中是新的

成员图标

- 表示 config 类型的类成员

- 表示 property 类型的类成员

- 表示 method 类型的类成员

- 表示 event 类型的类成员

- 表示 theme variable 类型的类成员

- 表示 theme mixin 类型的类成员

- 表示类、成员或指南在当前查看的版本中是新的

类成员快速导航菜单

在 API 文档页面上的类名正下方是一行按钮,对应于当前类拥有的成员类型。每个按钮显示按类型划分的成员计数(此计数在应用过滤器时会更新)。单击按钮会将您导航到该成员部分。将鼠标悬停在成员类型按钮上将显示该类型的所有成员的弹出菜单,以便快速导航。

Getter 和 Setter 方法

与类配置选项相关的 Getter 和 setter 方法将显示在方法部分以及 API 文档和成员类型菜单的配置部分中,紧靠其工作的配置下方。Getter 和 setter 方法文档将在配置行中找到,以便于参考。

历史记录栏

您的页面历史记录保存在本地存储中,并显示在顶部标题栏的正下方(使用可用的实际空间)。默认情况下,显示的唯一搜索结果是与您当前查看的产品/版本匹配的页面。您可以通过单击历史记录栏右侧的 按钮并选择“全部”单选选项来展开显示的内容。这将显示历史记录栏中所有产品/版本的所有最近页面。

在历史记录配置菜单中,您还将看到最近页面访问的列表。结果按“当前产品/版本”和“全部”单选选项进行过滤。单击 按钮将清除历史记录栏以及本地存储中保存的历史记录。

如果在历史记录配置菜单中选择“全部”,则将启用“在历史记录栏中显示产品详细信息”复选框选项。选中后,每个历史页面的产品/版本将在历史记录栏中的页面名称旁边显示。将光标悬停在历史记录栏中的页面名称上也会将产品/版本显示为工具提示。

搜索和过滤器

可以使用页面顶部的搜索字段搜索 API 文档和指南。

在 API 文档页面上,还有一个过滤器输入字段,该字段使用过滤器字符串过滤成员行。除了按字符串过滤外,您还可以按访问级别、继承和只读过滤类成员。这是通过使用页面顶部的复选框完成的。

API 类导航树底部的复选框过滤类列表以包含或排除私有类。

单击空的搜索字段将显示您最近 10 次搜索,以便快速导航。

API 文档类元数据

每个 API 文档页面(JavaScript 原始页面除外)都有一个与该类相关的元数据菜单视图。此元数据视图将具有以下一项或多项

展开和折叠示例及类成员

可运行的示例 (Fiddles) 默认在页面上展开。您可以使用代码块左上角的箭头单独折叠和展开示例代码块。您还可以使用页面右上角的切换按钮切换所有示例的折叠状态。切换所有状态将在页面加载之间记住。

类成员默认在页面上折叠。您可以使用成员行左侧的箭头图标或全局使用右上角的展开/折叠全部切换按钮来展开和折叠成员。

桌面 -vs- 移动视图

在较窄的屏幕或浏览器上查看文档将导致针对较小外形尺寸优化的视图。桌面视图和“移动”视图之间的主要区别在于

查看类源代码

可以通过单击 API 文档页面顶部的类名来查看类源代码。可以通过单击成员行右侧的“查看源代码”链接来查看类成员的源代码。

Ext JS 7.8.0 - Classic Toolkit


顶部
指南适用于: classic

Ext Direct 与 PHP 和 MySQL

大多数 Web 应用程序都需要使用客户端和服务器端。客户端代码不能直接调用服务器端函数。相反,客户端发送请求,服务器处理请求,然后将信息返回给客户端。Ext Direct 允许开发人员公开服务器端类的列表,然后可以直接从客户端代码调用这些类,从而大大简化了应用程序的构建过程。这允许您简化客户端和服务器端之间的通信,从而减少代码,在整个环境中实现命名奇偶校验,并实现更智能的 XHR 处理。其他好处包括

  • Ext Direct 是平台无关的,因此它可以与任何服务器端语言一起使用
  • 多个 Direct 函数调用捆绑到单个 Ajax 请求中(默认情况下,所有在第一个 10 毫秒内发送的请求),因此服务器只需发送回单个响应
  • 两个“提供程序”提供了多种与服务器通信的方式
    • Remoting Provider - 向客户端公开服务器端函数
    • Polling Provider - 允许通过定期轮询将事件从服务器发送到客户端

为了将其付诸实践,假设您有一个名为 Dog 的服务器端类,其中包含一个名为 bark 的方法。当使用 Ext Direct 时,您可以从 JavaScript 代码中调用 Dog.bark()

为此,您只需向 Ext Direct 提供服务器端类和方法的列表,Ext Direct 就会充当代理,让您能够从前端访问服务器端环境。

注意: 服务器端技术有很多变体,但本指南使用 Remoting Provider 以及 PHP 和 MySQL。

要求

  • 运行 PHP 5.3+ 的服务器
  • 运行 MySQL 4.1+ 的服务器
  • Ext JS 6+
  • Sencha Cmd

生成应用程序

首先,让我们使用 Sencha Cmd 生成一个应用程序。只需打开您的终端,然后发出以下命令

sencha -sdk path/to/ext/ generate app -classic DirectApp ./DirectApp

您现在应该有一个功能齐全的 Classic 应用程序。我们将使用此入门应用程序中预配置的视图来演示与 Ext Direct 的连接。

注意: 您的应用程序应该在 https://127.0.0.1/DirectApphttps://127.0.0.1:1841/ 上可用(如果您正在使用“sencha app watch”)。

Direct Proxy

我们的入门应用程序已经有一个 grid 显示姓名、电子邮件和电话号码。但是,它正在通过 内存代理 使用本地数据。让我们首先打开“app/store/Personnel.js”文件。打开后,删除 data 对象并将代理类型更改为“direct”,并添加 directFn “QueryDatabase.getResults”。这是我们将使用 PHP 创建的函数。生成的代码应如下所示

 Ext.define('DirectApp.store.Personnel', {
    extend: 'Ext.data.Store',

    alias: 'store.personnel',

    fields: [
        'name', 'email', 'phone'
    ],

    proxy: {
        type: 'direct',
        directFn: "QueryDatabase.getResults"
    },

    autoLoad: true
 });

刷新您的应用程序现在应该会导致一个空网格,因为我们尚未通过 direct proxy 提供任何数据。

填充数据库

让我们用一些已经适合姓名/电子邮件/电话字段的内容替换数据。使用此 SQL 创建一个“heroes”表

 DROP TABLE IF EXISTS `heroes`;

 CREATE TABLE `heroes` (
   `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
   `name` varchar(70) DEFAULT NULL,
   `email` varchar(255) DEFAULT NULL,
   `phone` varchar(10) DEFAULT NULL,
   PRIMARY KEY (`id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1;

 LOCK TABLES `heroes` WRITE;
 /*!40000 ALTER TABLE `heroes` DISABLE KEYS */;

 INSERT INTO `heroes` (`id`, `name`, `email`, `phone`)
 VALUES
      (1,'Thanos','[email protected]','5555555555'),
      (2,'Spider Man','[email protected]','2125555555'),
      (3,'Daredevil','[email protected]','2125555555'),
      (4,'The Maker','[email protected]','2125555555'),
      (5,'Rocket','[email protected]','5555555555'),
      (6,'Galactus','[email protected]','5555555555'),
      (7,'Silver Surfer','[email protected]','5555555555'),
      (8,'Hulk','[email protected]','2125555555'),
      (9,'Squirrel Girl','[email protected]','2125555555'),
      (10,'Thor','[email protected]','5555555555');

 /*!40000 ALTER TABLE `heroes` ENABLE KEYS */;
 UNLOCK TABLES;

您现在应该有一个填充了 10 条记录的 MySQL 表,我们将在网格中显示这些记录。现在我们有了数据,让我们创建一个连接。

创建查询

在应用程序的根目录中,创建一个名为“php”的文件夹,然后在其中创建一个名为“classes”的文件夹。在“classes”中创建一个名为“QueryDatabase.php”的文件。

我们将使用 PHP 的 MySQLi 扩展,它适用于 MySQL 4.1.3 及更高版本(2004 年年中之后发布的任何版本都可以)。

我们不会深入研究 PHP 代码。对于任何通过 PHP 查询 MySQL 的人来说,它的大部分内容都应该非常简单明了。我们正在定义一个新类,声明一些变量,创建一个连接器,并创建一个从数据库获取结果的函数。

 <?php

 class QueryDatabase {

    private $_db;
    protected $_result;
    public $results;

    public function __construct() {
        $this->_db = new mysqli('host', 'username' ,'password', 'database');

        $_db = $this->_db;

        if ($_db->connect_error) {
            die('Connection Error: ' . $_db->connect_error);
        }

        return $_db;
    }

    public function getResults($params) {
        $_db = $this->_db;

        $_result = $_db->query("SELECT name,email,phone FROM heroes") or
                   die('Connection Error: ' . $_db->connect_error);

        $results = array();

        while ($row = $_result->fetch_assoc()) {
            array_push($results, $row);
        }

        $this->_db->close();

        return $results;
    }

 }

概括地说,我们在类的顶部声明了一些变量,并创建了两个函数,这将有助于我们扩展应用程序。

第一个函数 (__construct) 创建数据库连接实例。如果连接失败,它将提供详细的错误消息。

第二个函数 (getResults) 使用第一个函数打开连接并查询数据库中的所有列字段。然后,我们通过 while 语句将所有结果推送到名为 $results 的数组中。最后,我们关闭与数据库的连接并返回结果。

注意:hostnamepassworddatabase 替换为您自己的凭据。

配置

让我们上一级到“php”目录,创建一个名为“config.php”的新文件,并添加以下代码

 <?php

 function get_extdirect_api() {

    $API = array(
        'QueryDatabase' => array(
            'methods' => array(
                'getResults' => array(
                    'len' => 1
                )
            )
        )
    );

    return $API;
 }

这公开了我们希望提供给 Ext 应用程序以调用服务器的函数。目前,我们只需要添加上面创建的“getResults”方法。

这就是我们 config.php 文件的全部内容。

路由器

接下来,我们将需要一个路由器来确保调用正确的方法。路由器是来自 Ext Direct 的调用使用远程过程调用 (RPC) 路由到正确类的地方。

在“php”目录中,让我们创建另一个名为“router.php”的文件并添加以下代码。

 <?php
 require('config.php');

 class BogusAction {
    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'])){ // form post
    $isForm = true;
    $isUpload = $_POST['extUpload'] == 'true';
    $data = new BogusAction();
    $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){
    $API = get_extdirect_api('router');

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

        $action = $cdata->action;
        $a = $API[$action];

        $method = $cdata->method;
        $mdef = $a['methods'][$method];

        if (!$mdef){
            throw new Exception("Call to undefined method: $method " .
                                "in action $action");
        }

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

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

        if (isset($mdef['len'])) {
            $params = isset($cdata->data) && is_array($cdata->data) ? $cdata->data : array();
        }
 else {
            $params = array($cdata->data);
        }

        array_push($params, $cdata->metadata);

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

    catch(Exception $e){
        $r['type'] = 'exception';
        $r['message'] = $e->getMessage();
        $r['where'] = $e->getTraceAsString();
    }

    return $r;
 }

 $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 公开定义的方法的配置文件。我们还添加了一个 doRpc 函数,该函数将提供有关我们来自服务器的数据和响应的重要信息。

注意: 更高级版本的 router.php(以及下一节中的 api.php)可以在 SDK 中的“ext/examples/kitchensink/data/direct”文件夹中找到。

API

最后,让我们创建一个名为“api.php”的文件,并使用以下代码填充它

 <?php
 require('config.php');
 header('Content-Type: text/javascript');

 // convert API config to Ext Direct spec
 $API = get_extdirect_api();
 $actions = array();

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

 $cfg = array(
    'url'=>'php/router.php',
    'type'=>'remoting',
    'actions'=>$actions
 );

 echo 'var Ext = Ext || {}; Ext.REMOTING_API = ';

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

此文件使用我们之前制作的“config.php”文件,并将输出标头设置为 JavaScript。这确保浏览器会将任何输出解释为 JavaScript。然后,它继续将我们的 config 和 router PHP 文件转换为 JSON,以便在 Ext Direct 调用时调用正确的方法。

同样,“api.php”的内容可以在 SDK 中的“ext/examples/kitchensink/data/direct”文件夹中找到。

更新 app.json

接下来,让我们告诉 Cmd 关于“api.php”,应用程序的 Direct 的“入口点”。将我们的需求传达给 Cmd 的最佳方法是通过“app.json”的 javascript 数组。打开“app.json”并找到 JS 数组。然后添加“api.php”作为远程包含。生成的数组应如下所示

 "js": [
    {
        "path": "php/api.php",
        "remote": true
    },
    {
        "path": "app.js",
        "bundle": true
    }
 ],

如果您未使用 Cmd 构建应用程序,则可以将“api.php”添加到应用程序的“index.html”文件中的 script 标记中。只需确保“api.php”行位于“app.js”行之前。

 <!DOCTYPE html>
 <html>
 <head>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
     <title>App Title</title>
     <!--Ext JS-->
     <link rel="stylesheet" type="text/css" href="resources/css/ext-all.css">
     <script src="extjs/ext-all-debug.js"></script>
     <!--Application JS→
     <script src="php/api.php"></script>
     <script src="app.js"></script>
 </head>
 <body>
 </body>
 </html>

因为我们使用的是 HTML5 文档类型,所以我们可以在 script 标记中省略 type,它假定所有 <script> 标记都将是 JavaScript,这有助于减少我们的字节数。

Provider

我们已经到了最后一步,用结果填充网格!我们现在需要向 direct manager 添加一个 provider。正如我们之前讨论的,框架中有两个提供程序,但对于这个特定项目,我们将使用 remoting api。打开您的“Application.js”文件,并将 provider 添加到 launch 函数中的 direct manager。它应该像这样

 launch: function () {
    Ext.direct.Manager.addProvider(Ext.REMOTING_API);
 },

注意: “Ext.REMOTING_API”是“api.php”中打印的 JavaScript 代码创建的变量的名称。您可以使用任何您喜欢的变量名称,但它在两个地方都应该相同。

结论

刷新您的应用程序现在应该显示我们的新网格结果。如您所见,涉及一些设置,但一旦完成,添加新方法只需编写它们并将它们添加到您的配置文件中即可。然后,您可以直接访问服务器端方法,从而简化您的代码等等!

Ext JS 7.8.0 - Classic Toolkit