
在ext js应用中,数据管理的核心在于ext.data.store。store充当着客户端数据缓存的角色,它与服务器的通信则通过ext.data.proxy.proxy完成。当store需要从服务器获取数据时,proxy会负责发送请求;而当服务器返回数据后,ext.data.reader.reader则负责解析响应,将原始数据转换为store能够理解和存储的ext.data.model实例。
一个典型的Store配置会指定其使用的Proxy类型和数据读取器。例如,使用ajax类型的Proxy可以向指定的URL发送HTTP请求。
Ext.define("ModernApp.view.form.FormViewStore", {
extend: "Ext.data.Store",
alias: "store.formviewstore", // 使用'store.'前缀作为别名
proxy: {
type: "ajax",
url: "https://jsonplaceholder.typicode.com/posts", // 目标API地址
reader: {
type: "myreader", // 指定自定义读取器
},
},
});在这个配置中,url定义了数据请求的目标地址,reader属性则指向了一个自定义的读取器,其别名为myreader。
自定义数据读取器通常继承自Ext.data.reader.Json或Ext.data.reader.Xml,并重写getResponseData方法。这个方法是数据解析的关键,它接收原始的服务器响应对象,并负责将其转换为Store期望的格式(通常是一个包含success状态和data或results数组/对象的JavaScript对象)。
Ext.define("ModernApp.view.form.reader.Json", {
extend: "Ext.data.reader.Json",
alias: "reader.myreader", // 使用'reader.'前缀作为别名
getResponseData: function (response) {
let decodedData;
try {
// 尝试解析原始响应文本为JSON对象
decodedData = Ext.JSON.decode(response.responseText);
} catch (e) {
console.error("JSON解析失败:", e);
// 返回一个表示失败的结构
return { success: false, errors: [{ message: "无效的JSON响应" }] };
}
// 根据HTTP状态码和解析后的数据构建Store期望的格式
if (response.status === 200) {
// 假设API成功时直接返回数据,我们将其包装在'results'中
return {
success: true,
results: decodedData, // 这里的decodedData可以是单个对象或数组
};
} else {
// 处理非200状态码,假设decodedData可能包含错误信息
return {
success: false,
errors: decodedData.errors || [{ message: `服务器错误: ${response.status}` }],
};
}
},
});在getResponseData方法中,我们首先尝试使用Ext.JSON.decode解析response.responseText。然后,根据HTTP状态码和解析结果,构造一个包含success标志和results(或data)属性的对象。这是Store期望的格式,以便它能正确地加载数据。
一个常见的误解是,所有Ext JS组件都可以通过简单的store配置直接绑定Store。实际上,并非所有组件都支持此配置。例如,Ext.form.Panel组件设计用于显示和编辑单个Ext.data.Model实例,而不是像Ext.grid.Panel那样直接管理一个Store的数据集合。因此,直接在Ext.form.Panel中配置store: { type: "formviewstore" }是无效的,并不会自动触发数据加载。
要触发Store的AJAX请求,需要手动创建Store实例并调用其load()方法。这可以在组件的控制器中,或在某个事件处理器中完成。
Ext.define("ModernApp.view.form.FormView", {
extend: "Ext.form.Panel",
xtype: "formview",
title: "Custom Form",
controller: "formviewcontroller",
// ... 其他配置 ...
buttons: [
{
text: "发送请求",
handler: function () {
// 创建FormViewStore实例
const store = Ext.create("ModernApp.view.form.FormViewStore");
// 调用load()方法触发AJAX请求
store.load({
callback: function (records, operation, success) {
if (success) {
console.log("数据加载成功:", records);
// 假设我们只需要第一个记录来填充表单
if (records && records.length > 0) {
this.up("formview").setRecord(records[0]); // 将第一个记录设置到表单中
}
} else {
console.error("数据加载失败:", operation.getError());
}
},
scope: this, // 确保callback中的this指向当前按钮
});
},
},
{
text: "取消",
handler: "onCancel",
},
],
// ... 其他items和listeners ...
});在上述示例中,当“发送请求”按钮被点击时,我们动态创建了FormViewStore的一个实例,并调用了store.load()。load()方法可以接受一个callback函数,用于处理请求成功或失败后的逻辑,例如将加载到的数据填充到表单中。
更推荐的做法是在组件的控制器中管理Store的生命周期和数据加载逻辑,以保持视图和逻辑的分离。
// ModernApp.view.form.FormViewController.js
Ext.define("ModernApp.view.form.FormViewController", {
extend: "Ext.app.ViewController",
alias: "controller.formviewcontroller",
onFormRender: function () {
console.log("表单渲染完成");
this.loadFormData();
},
loadFormData: function () {
// 获取或创建Store实例
const store = Ext.create("ModernApp.view.form.FormViewStore");
store.load({
callback: function (records, operation, success) {
if (success) {
console.log("表单数据加载成功:", records);
if (records && records.length > 0) {
this.getView().setRecord(records[0]); // 将第一个记录设置到当前表单
}
} else {
console.error("表单数据加载失败:", operation.getError());
}
},
scope: this, // 确保callback中的this指向控制器
});
},
onSubmit: function () {
// 处理表单提交逻辑
const form = this.getView();
const record = form.getRecord();
if (record) {
// 假设record已经加载,可以进行修改并保存
record.set(form.getValues());
// record.save(); // 如果需要将修改保存回服务器
} else {
console.warn("没有记录可提交。");
}
},
onCancel: function () {
// 处理取消逻辑
const form = this.getView();
form.reset(); // 重置表单字段
},
});在这个控制器中,onFormRender监听表单的afterrender事件,并在表单渲染完成后调用loadFormData方法来加载数据。这种方式使得数据加载逻辑更加集中和可控。
一旦Store被成功加载,其包含的数据就可以通过Store实例进行访问。如果需要在一个组件中加载数据,并在另一个组件中使用这些数据,有几种方法可以实现:
通过Store ID引用: 如果Store在应用中是唯一的且需要在多个地方访问,可以为其指定一个storeId。然后,其他组件可以通过Ext.getStore('myStoreId')来获取Store实例。
// FormViewStore.js
Ext.define("ModernApp.view.form.FormViewStore", {
extend: "Ext.data.Store",
alias: "store.formviewstore",
storeId: "myFormDataStore", // 添加一个唯一的storeId
// ...
});
// 在NavView组件中访问
Ext.define("ModernApp.view.nav.NavView", {
extend: "Ext.Panel",
xtype: "navview",
listeners: {
afterrender: function () {
const store = Ext.getStore("myFormDataStore");
if (store && store.isLoaded()) {
console.log("NavView访问到的数据:", store.getData().items);
// ... 使用数据更新NavView ...
} else if (store) {
// 如果Store尚未加载,可以监听其load事件
store.on("load", function (s, records) {
console.log("NavView监听到的数据:", records);
// ...
}, this, { single: true }); // 只监听一次
store.load(); // 如果NavView是第一个需要数据的,也可以在此处触发加载
}
},
},
});通过组件引用传递: 可以在一个组件中加载Store,然后将Store实例或其数据作为参数传递给另一个组件。
使用ViewModel: 对于更复杂的应用,可以利用Ext.app.ViewModel在组件层级之间共享数据。ViewModel可以绑定到Store,并在其关联的视图或子视图中提供数据。
通过本教程,我们深入理解了Ext JS中Store、Proxy和自定义Reader协同工作以处理AJAX请求的机制。关键在于正确配置Store的Proxy和Reader,并在适当的时机手动调用Store的load()方法来触发数据请求。特别是对于Ext.form.Panel这类不直接绑定Store的组件,手动加载Store并在回调中处理数据填充是标准做法。同时,通过storeId或控制器层级管理,可以有效地在不同组件间共享和访问加载后的数据,构建功能完善的Ext JS应用。
以上就是Ext JS AJAX请求:通过代理与自定义读取器高效管理数据的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号