关于在Ext.data.Model中使用mapping无效
先定义一个简单的Model:
Ext.define("ProductModel", { extend: "Ext.data.Model", fields: [ { name: "product", // mapping: "p.name" // 这种写法也可以,使用下面的function是为了调试 mapping: function(data) { // alert(data.p.name); return data.p.name; } }, {name: "sl", type: "int"} ] });
上面的model很基础,没什么可说的。再创建一个Store:
var productStore = Ext.create("Ext.data.Store", { storeId: "productStore", model: "ProductModel", data: [{ p: { name: "product1", brand: "b1" }, sl: 11 }, { p: { name: "product2", brand: "b2" }, sl: 22 }] });
最后是grid panel:
var productGP = Ext.create("Ext.grid.Panel", { border: false, store: productStore, columnLines: true, columns: { items: [ {xtype: "rownumberer", resizable: true}, {text: "产品", dataIndex: "product", flex: 1}, {text: "数量", dataIndex: "sl"} ] } });
上述代码的本意是希望在grid panel的产品列中显示产品的名称,然而实际结果却是[Object Object]。经过调试发现,fields里面的mapping根本没起作用,这让我百思不得其解,求助google也没找到合适的答案。
正当心灰意冷时,我在extjs的api文档中发现端倪。首先请注意到我的store中使用了inline data,而在store的api文档中,Inline data小节有如下描述:
就是说,inline data是不会经过任何加工处理的,如果要对数据进行加工,可考虑使用MemoryProxy。
好的,对上述代码进行改造,为store添加一个MemoryProxy:
var productStore = Ext.create("Ext.data.Store", { storeId: "productStore", model: "ProductModel", data: [{ p: { name: "product1", brand: "b1" }, sl: 11 }, { p: { name: "product2", brand: "b2" }, sl: 22 }], proxy: { type: "memory", reader: { type: "json" } } });
这样一来,mapping就起作用了,gridpanel也如我们所预期的那样显示了产品名称。
但是实际应用中,数据一般都是通过向服务器请求获得的,而不是这样写死在代码中。我个人习惯定义一个方法,在方法中发送一个Ext.Ajax.request请求,该方法接受一个object参数,该参数将作为Ext.Ajax.request请求的params。需要加载/更新数据的时候调用这个方法。为了方便,在此我只贴出Ext.Ajax.request的代码,并且也只给出了success情况下的处理:
Ext.Ajax.request({ url: getContextPath() + "/test/extMappingTest", // 你的请求地址 params: param, // 请求参数 reader: "json", actionMethods: { read: "POST" }, success: function(response) { var resp = Ext.JSON.decode(response.responseText); // 服务器返回的是json格式的字符串,这里将其解析为一个Object productStore.removeAll(); // 清除原有数据 productStore.loadData(resp); } });
上述代码的实际运行结果并没有达到我们的预期,gridpanel没有正确显示出产品名称,只显示出数量。通过调试可以发现,和一开始使用Inline data一样,mapping根本没起作用。不过既然我们已经有了经验,知道必须通过proxy加载数据才会经过mapping的处理,那我们就手动调用proxy好了。将Ext.Ajax.request修改如下:
Ext.Ajax.request({ url: getContextPath() + "/test/extMappingTest", // 你的请求地址 params: param, // 请求参数 reader: "json", actionMethods: { read: "POST" }, success: function(response) { var resp = Ext.JSON.decode(response.responseText); // 服务器返回的是json格式的字符串,这里将其解析为一个Object productStore.removeAll(); // 清除原有数据 var rs = productStore.getProxy().getReader().readRecords(resp); // 如想Model中fields里的mapping生效,必须通过proxy处理数据 productStore.loadRecords(rs.records); } });
至此,大功告成。
推荐阅读
-
关于在vscode使用webpack指令显示"因为在此系统中禁止运行脚本"问题(完美解决)
-
在Python中关于使用os模块遍历目录的实现方法
-
在iOS开发中关于NSUserDefaults的使用解析
-
关于使用了@EnableRedisHttpSession注解,在配置文件中加入timeout 无效的原因
-
关于微信码的存储和使用(个人建议存储在reids中)-柚果云开发日志
-
关于bootstrap的datepicker在meteor应用中的使用(不包含bootstrap框架)
-
在Python中关于使用os模块遍历目录的实现方法
-
关于在Ext.data.Model中使用mapping无效
-
“/”应用程序中的服务器错误。 回发或回调参数无效。在配置中使用 <pages enableEventValidation=“true“/> 或在页面中使用 <%@ Page EnableEventV
-
在iOS开发中关于NSUserDefaults的使用解析