关于在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小节有如下描述:

Loading inline data using the method above is great if the data is in the correct format already (e.g. it doesn't need to be processed by a reader). If your inline data requires processing to decode the data structure, use a MemoryProxy instead (see the MemoryProxy docs for an example).

 就是说,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);
	}
});

 至此,大功告成。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值