
Ext.Direct 简介
ext.direct 是 ext js 框架提供的一种机制,用于在客户端 javascript 代码中无缝调用服务器端方法。它通过将服务器端方法映射到客户端 javascript 对象,简化了前后端通信,使得开发者可以像调用本地 javascript 函数一样调用远程服务。通常,ext.direct 会与 ext.data.store 结合使用,以自动加载数据。
常见问题:直接调用方法时遇到 ReferenceError
在使用 Ext.Direct 时,一个常见的场景是,虽然通过 Ext.data.Store 配置 directFn 可以成功从服务器获取数据,但在 JavaScript 代码中尝试直接调用这些方法时(例如 RaStatuses.get_ra_statuses()),却会遇到 ReferenceError: RaStatuses is not defined 的错误。
例如,以下 Ext.data.Store 配置可以正常工作,并成功填充数据:
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
});然而,当尝试在其他 JavaScript 函数中直接调用此方法时:
a = RaStatuses.get_ra_statuses(); // 导致 'ReferenceError: RaStatuses is not defined'
这表明尽管 Ext.Direct 代理能够识别并调用服务器方法,但该方法对应的客户端对象并未全局暴露或以可访问的方式注册。
问题分析与解决方案
ReferenceError 的出现通常是因为 Ext.Direct API 的配置不完整,导致其提供的远程方法未能被正确地注册到全局命名空间或可访问的对象中。为了解决这个问题,我们需要在服务器端生成 Ext.Direct API 配置时,确保以下几个关键点:
- 定义命名空间(Namespace): 为 Ext.Direct 服务定义一个明确的命名空间,避免与全局变量冲突,并提供结构化的访问方式。
- 指定命名空间和描述符: 在 API 配置中明确指出所使用的命名空间和描述符。
- 注册提供者(Provider): 将生成的 API 配置作为提供者添加到 Ext.direct.Manager 中,这是 Ext.Direct 机制启动和管理远程服务的核心步骤。
以下是经过修正的 api.php 返回内容,它解决了上述 ReferenceError 问题:
采用HttpClient向服务器端action请求数据,当然调用服务器端方法获取数据并不止这一种。WebService也可以为我们提供所需数据,那么什么是webService呢?,它是一种基于SAOP协议的远程调用标准,通过webservice可以将不同操作系统平台,不同语言,不同技术整合到一起。 实现Android与服务器端数据交互,我们在PC机器java客户端中,需要一些库,比如XFire,Axis2,CXF等等来支持访问WebService,但是这些库并不适合我们资源有限的android手机客户端,
Ext.namespace('RPC'); // 1. 定义一个全局命名空间 'RPC'
var Ext = Ext || {};
RPC.REMOTING_API = {
"url": "php/api/router.php",
"type": "remoting",
"namespace": "RPC", // 2. 指定此 API 配置的命名空间
"descriptor": "RPC.REMOTING_API", // 3. 指定此 API 配置的描述符
"actions": {
"RaStatuses": [{
"name": "get_ra_statuses",
"len": 0 // 注意:这里 len 应与服务器端方法的参数数量匹配
}]
}
};
// 4. 将此 API 配置作为提供者添加到 Ext.direct.Manager
Ext.direct.Manager.addProvider(RPC.REMOTING_API);关键修改点解释:
- Ext.namespace('RPC');: 这行代码创建了一个名为 RPC 的全局 JavaScript 对象。所有由这个 Ext.Direct 提供者暴露的方法都将挂载到这个命名空间下。
- "namespace": "RPC": 在 REMOTING_API 配置中,namespace 属性明确告诉 Ext.Direct 框架,它应该将所有 actions 中的方法注册到 RPC 这个命名空间下。
- "descriptor": "RPC.REMOTING_API": descriptor 属性通常用于指定描述此 API 的全局变量名,这在某些内部机制中可能有用,但主要作用是与 namespace 协同工作。
- Ext.direct.Manager.addProvider(RPC.REMOTING_API);: 这是最关键的一步。它将我们定义的 RPC.REMOTING_API 配置注册为 Ext.Direct 的一个提供者。一旦注册,Ext.Direct 框架就会解析 actions 中定义的方法,并根据 namespace 属性在客户端创建相应的可调用对象。
正确的客户端调用方式
经过上述配置后,之前无法直接调用的方法现在可以通过指定的命名空间进行访问:
// 现在,这个调用将成功返回数据 RPC.RaStatuses.get_ra_statuses();
通过 RPC. 前缀,我们明确地访问了在 RPC 命名空间下注册的 RaStatuses 对象及其方法 get_ra_statuses。
总结与注意事项
- 完整性是关键: 确保 Ext.Direct API 配置不仅包含 url、type 和 actions,还要有 namespace 和 descriptor 属性,并且最重要的是通过 Ext.direct.Manager.addProvider() 方法进行注册。
- 命名空间管理: 使用 Ext.namespace() 定义一个明确的命名空间是良好的实践,它有助于组织代码,避免全局变量污染,并提高代码的可维护性。
- 参数长度 (len): 在 actions 配置中,len 属性表示服务器端方法期望的参数数量。务必确保其与实际的服务器端方法签名匹配,否则可能导致参数传递错误。
- Ext JS 版本: 本文的解决方案在 Ext JS 6.0.2 版本中验证有效。不同版本的 Ext JS 在 Ext.Direct 的实现细节上可能略有差异,但核心原理(命名空间、提供者注册)通常保持一致。
- 调试技巧: 如果仍然遇到问题,可以使用浏览器的开发者工具检查网络请求(确认 api.php 返回的 JavaScript 代码是否正确加载和执行),并在控制台中检查 RPC 对象是否存在以及其内部结构。
通过遵循这些步骤和最佳实践,开发者可以确保 Ext.Direct 服务端方法在客户端 JavaScript 中得到正确且方便的直接调用。









