理解 Ext.Direct 远程调用机制
ext.direct 是 ext js 框架提供的一种强大的机制,用于在客户端 javascript 和服务器端之间进行无缝的远程过程调用(rpc)。它允许开发者像调用本地 javascript 函数一样调用服务器端方法,极大地简化了前后端通信的复杂性。
在使用 Ext.Direct 时,通常会定义一个 REMOTING_API 对象,其中包含了服务器端方法的元数据,例如 URL、类型、以及可用的动作(actions)和方法。这个 API 配置通常通过一个单独的 PHP 文件(例如 api.php)动态生成并加载到客户端。
一个常见的场景是,当 Ext.data.Store 配置了 directFn 时,它能够成功地通过 Ext.Direct 调用服务器方法来加载数据。例如:
Ext.define('CSM.store.ra.Statuses', { extend: 'Ext.data.Store', model: 'CSM.model.ra.Status', proxy: { type: 'direct', directFn: "RaStatuses.get_ra_statuses" // 这里可以正常工作 }, autoLoad: true});登录后复制
然而,开发者可能会遇到一个问题:尽管 directFn 在 Store 中工作正常,但尝试在普通的 Javascript 函数中直接调用 RaStatuses.get_ra_statuses() 却会收到 ReferenceError: RaStatuses is not defined 的错误。这表明 Ext.Direct 提供的远程方法对象并未如预期那样全局可用。
核心问题:ReferenceError 及其根源
ReferenceError 的出现,其根本原因在于 Ext.Direct 的 REMOTING_API 配置虽然定义了可用的远程方法,但默认情况下,它并没有将这些方法直接挂载到全局作用域或一个可访问的命名空间下。Ext.REMOTING_API 只是一个数据结构,描述了如何与后端交互,但要让这些描述转化为可调用的 Javascript 函数,还需要额外的步骤。
立即学习“Java免费学习笔记(深入)”;
最初的 api.php 可能只简单地定义了 Ext.REMOTING_API:
var Ext = Ext || {};Ext.REMOTING_API = { "url": "php/api/router.php", "type": "remoting", "actions": { "RaStatuses": [{ "name": "get_ra_statuses", "len": 1 }] }};登录后复制
这样的配置仅供 Ext.Direct 内部机制(如 Ext.data.proxy.Direct)使用。要使其方法在客户端 Javascript 中可直接调用,必须明确地定义一个命名空间,并将该 API 提供者注册到 Ext.Direct 管理器中。
解决方案:正确配置和注册 Ext.Direct API
要解决 ReferenceError 问题,需要对 api.php 文件进行以下关键修改:
1. 定义命名空间
首先,使用 Ext.namespace() 定义一个全局命名空间,用于挂载 Ext.Direct 提供的远程方法。这有助于避免全局变量污染,并提供清晰的组织结构。
Ext.namespace('RPC');登录后复制
这里,我们创建了一个名为 RPC 的命名空间。所有通过 Ext.Direct 暴露的方法都将挂载到 RPC 对象下。

法语助手旗下的AI智能写作平台,支持语法、拼写自动纠错,一键改写、润色你的法语作文。


2. 配置 REMOTING_API 对象
在 REMOTING_API 配置中,除了 url、type 和 actions 外,还需要添加 namespace 和 descriptor 属性。
namespace: 指定了远程方法将挂载到的全局对象名称。它应该与你在步骤1中定义的命名空间一致。descriptor: 这是 Ext.Direct 内部用于标识和管理此 API 提供者的字符串。通常,它会结合命名空间和 REMOTING_API 本身来命名。同时,确保 actions 中的 len 属性与服务器端方法期望的参数数量匹配。len: 0 表示该方法不接受任何参数。
3. 注册 API 提供者
最后,也是最关键的一步,是将配置好的 REMOTING_API 对象注册到 Ext.Direct 的管理器中。这通过 Ext.direct.Manager.addProvider() 方法完成。
Ext.direct.Manager.addProvider(RPC.REMOTING_API);登录后复制
当 Ext.Direct 管理器添加了提供者后,它会根据 namespace 属性在全局作用域下创建相应的对象(如果不存在),并将 actions 中定义的方法作为属性挂载到该对象上。
完整的 api.php 示例
结合上述步骤,修正后的 api.php 内容应类似于:
// 确保 Ext 对象存在var Ext = Ext || {};// 定义一个命名空间,所有 Direct 方法将挂载到此命名空间下Ext.namespace('RPC');// 配置 REMOTING_API,包含 namespace 和 descriptorRPC.REMOTING_API = { "url": "php/api/router.php", // 后端路由地址 "type": "remoting", // 类型为 remoting "namespace": "RPC", // 远程方法将挂载到全局 RPC 对象下 "descriptor": "RPC.REMOTING_API", // 描述符,用于内部管理 "actions": { // 定义可用的远程方法 "RaStatuses": [{ // RaStatuses 是一个 Action 类 "name": "get_ra_statuses", // 方法名 "len": 0 // 方法期望的参数数量 }] }};// 将此 API 提供者注册到 Ext.direct.Manager// 这一步是关键,它使得 RPC.RaStatuses.get_ra_statuses() 变得可用Ext.direct.Manager.addProvider(RPC.REMOTING_API);登录后复制
调用 Ext.Direct 远程方法
在 api.php 文件正确配置并加载后,你就可以在客户端 Javascript 中通过指定的命名空间来调用远程方法了:
// 现在,这个调用将返回数据,而不会抛出 ReferenceErrorRPC.RaStatuses.get_ra_statuses({ success: function(result, event) { console.log("数据已成功获取:", result); }, failure: function(error, event) { console.error("数据获取失败:", error); }});登录后复制
注意: Ext.Direct 方法调用通常是异步的,并支持配置 success 和 failure 回调函数来处理结果。即使 len 为 0,也可以传递一个配置对象作为参数,其中包含回调函数。
注意事项
len 属性的重要性: len 属性定义了服务器端方法期望的参数数量。如果客户端调用时提供的参数数量与 len 不匹配,可能会导致服务器端错误或意外行为。请确保 api.php 中定义的 len 与后端方法的实际参数数量一致。后端服务匹配: router.php 或其他后端路由文件需要正确地处理 Ext.Direct 请求,并根据 action 和 method 调用相应的服务器端逻辑。服务器端方法的签名(参数数量和类型)应与 REMOTING_API 中的定义相符。加载顺序: 确保 api.php 文件在 Ext JS 框架和你的应用程序代码加载之前或加载过程中被正确引入。通常,它会在 Ext.onReady() 或应用程序启动逻辑之前加载。调试技巧: 如果遇到问题,可以使用浏览器开发者工具检查 window.RPC 对象是否已创建,以及其中是否包含 RaStatuses 和 get_ra_statuses 方法。你也可以通过 Ext.direct.Manager.getProvider('RPC') 来检查提供者是否已成功注册。命名空间选择: 选择一个独特且有意义的命名空间,以避免与其他库或应用程序组件发生冲突。总结
在 Ext.Direct 中,仅仅定义 Ext.REMOTING_API 不足以使远程方法在全局 Javascript 中直接可用。关键在于通过 Ext.namespace() 定义一个明确的命名空间,在 REMOTING_API 配置中指定 namespace 和 descriptor 属性,并最终使用 Ext.direct.Manager.addProvider() 将这个 API 提供者注册到 Ext.Direct 管理器中。遵循这些步骤,将确保 Ext.Direct 远程方法能够被正确地识别和调用,从而实现前后端之间高效且可维护的通信。
以上就是掌握 Ext.Direct:在 Javascript 中正确调用远程方法的详细内容,更多请关注php中文网其它相关文章!