Extjs 嵌套模型和如何保存为json字符串

1.嵌套模型(nested model)

    在model中使用hasmany可以定义父子结构的嵌套模型,举一个实际的例子:Chart模型中包含坐标轴YAxis,Cell,Serie和PolyLine四个子模型,代码如下所示,hasmany定义了父子关系,当我们得到一个chart实例时,可以通过chart.Cells()得到以Cell为model的store。

Ext.define('Arim.model.chart.Chart', {
	extend: 'Arim.model.Base',
	requires: [
		'Arim.model.chart.PlotLine',
		'Arim.model.chart.Cell',
		'Arim.model.chart.Serie',
		'Arim.model.chart.YAxis'
	],
	fields: [
		{ name: 'Name', type: 'string' },
		{ name: 'Group', type: 'string' },
		{ name: 'Inter', type: 'int' },
		{ name: 'Categories', type: 'string' }
	],
	idProperty: 'Name',

	proxy: {
		type: 'memory',
		reader: {
			type: 'json'
		},
		writer: new Ext.data.JsonWriter({
			getRecordData: function (record) {
				Ext.apply(record.data, record.getAssociatedData());
				return record.data;
			}
		})
	},

	hasMany: [
		{ model: 'Arim.model.chart.PlotLine', name: 'PlotLines', associationKey:'PlotLines' },
		{ model: 'Arim.model.chart.Cell', name: 'Cells', associationKey:'Cells'  },
		{ model: 'Arim.model.chart.Serie', name: 'Series', associationKey:'Series'  },
		{ model: 'Arim.model.chart.YAxis', name: 'YAxises', associationKey:'YAxises'  }
	]
});
Ext.define('Arim.model.chart.PlotLine', {
    extend: 'Arim.model.Base',
    fields: [
		{name:'Axis',type:'string'},
		{name:'Color', type:'string'},
		{name:'DashStyle', type:'string'},
		{name:'Id', type:'int'},
		{name:'Value',type:'int'},
		{name:'Label',type:'string'},
		{name:'Width',type:'int'},
		{name:'zIndex', type:'int'}],
	idProperty:'Id'
});
Ext.define('Arim.model.chart.Cell', {
    extend: 'Arim.model.Base',
    fields: [
		{name:'Name', type:'string'},
		{name:'PropertyId', type:'int'},//属性id
		{name:'TagId', type:'int'},//标签id
		{name:'Act',type:'int'},
		{name:'Offset',type:'int'},
		{name:'Inter',type:'int'},
		{name:'Unit', type:'string'},
		{name:'Data', type:'float'},
		{name:'InterCount', type:'int'},
		{name:'Fun',type:'string'}],
	idProperty:'Name'
});
Ext.define('Arim.model.chart.Serie', {
    extend: 'Arim.model.Base',
    fields: [
		{name:'Name', type:'string'},
		{name:'Type', type:'string', defaultValue:'曲线'},
		{name:'ShowInLegend', type:'boolean', defaultValue:true},
		{name:'YAxis', type:'int', defaultValue:0},
		{name:'X', type:'string'},
		{name:'Y'},
		{name:'Z'},
		{name:'Used', type:'boolean', defaultValue:false},
		{name:'stack',type:'string'}],	  
	idProperty:'Name'
});

 2.嵌套模型的编辑

    有了父子结构,我们可以设计一个form,里下包含多个grid,每个子模型关联一个grid,用来编辑Chart,对于Chart的属性可以用form.loadRecord(chart)加载,对于子模型则可以用grid.reconfigure(chart.Cells())加载。修改完成后,可以通过form.updateRecord(chart)得到修改后的chart,将chart提交到后台。form的设计代码如下。

Ext.define('Arim.view.chart.Template', {
	extend: 'Ext.form.Panel',
	alias: 'widget.charttemplate',

	requires: [
		'Arim.model.chart.Chart',
		'Arim.view.chart.config.Cells',
		'Arim.view.chart.config.PlotLine',
		'Arim.view.chart.config.Series',
		'Arim.view.chart.config.YAxis',
		'Arim.view.chart.TemplateController'
	],

	autoScroll: true,
	controller: 'charttemplate',

	create: true,
	template: {},

	bodyPadding: 10,
	closable: true,

	layout:  {
		type: 'vbox',
		defaultMargins: '5,0,0,0',
		align: 'stretch'
	},

	items: [{
		xtype: 'fieldset',
		layout: 'hbox',
		items: [{
			xtype: 'textfield',
			fieldLabel: '标题',
			labelAlign: 'right',
			name: 'Name',
			itemId: 'name',
			flex:4
		}, {
			xtype: 'textfield',
			fieldLabel: '分组',
			labelAlign: 'right',
			name: 'Group',
			itemId: 'group',
			flex:3
		}, {
			xtype: 'combobox',
			hideLabel: true,
			queryMode: 'local',
			store: 'ChartIntertype',
			displayField: 'Text',
			valueField: 'Value',
			itemId: 'inter',
			name:'Inter',
			value: 86400,
			editable: false
		}, {
			icon: 'resources/icons/spline.png',
			xtype: 'splitbutton',
			itemId: 'serie',
			text: '曲线',
			enableToggle: true,
			listeners: {
				toggle: 'seriebtntoggle'
			},
			menu: {
				itemId: 'serietypemenu',
				items: [
					{ icon: 'resources/icons/spline.png', 'text': '曲线', handler: 'seriebtnmenuclick' },
					{ icon: 'resources/icons/pie.png', 'text': '饼图', handler: 'seriebtnmenuclick' },
					{ icon: 'resources/icons/column.png', 'text': '柱状图', handler: 'seriebtnmenuclick' },
					{ icon: 'resources/icons/stackcolumn.png', 'text': '叠加柱状图', handler: 'seriebtnmenuclick' },
					{ icon: 'resources/icons/area3d.png', 'text': '面积图', handler: 'seriebtnmenuclick' },
					{ icon: 'resources/icons/stackarea.png', 'text': '叠加面积图', handler: 'seriebtnmenuclick' },
					{ icon: 'resources/icons/scatter.png', 'text': '散点图', handler: 'seriebtnmenuclick' },
					{ icon: 'resources/icons/bubble.png', 'text': '气泡图', handler: 'seriebtnmenuclick' }
				]
			},
			flex:1
		}]
	}, {
		xtype: 'textfield',
		fieldLabel: 'x轴类别',
		labelAlign: 'right',
		name: 'Categories',
		itemId: 'categories'
	}, {
		xtype: 'chartyaxis',
		itemId: 'yaxisgrid',
		name: 'YAxises'
	}, {
		xtype: 'chartplotLine',
		itemId: 'plotlinegrid',
		name: 'PlotLine'
	}, {
		xtype: 'chartseries',
		itemId: 'seriesgrid',
		name: 'Series'
	}, {
		xtype: 'chartcells',
		itemId: 'cellsgrid',
		name: 'Cells'
	}],
	buttons: [{
		text: '保存',
		itemId: 'submit',
		handler: 'acceptChange'
	}],

	listeners: {
		afterrender: 'afterrender',
		destroy: 'destroy'
	}
});	

  3.将嵌套模型encode得到json字符串

     当使用嵌套模型(nested model)时,通过proxy直接向后台提交可以将模型的层次化json保存,load时也可以将后台返回的json构建出嵌套模型实例,这其中的工作是由proxy里面的reader, writer完成的。如果要把嵌套模型在前端encode得到字符串则只有父级的属性保存,子集信息丢失,decode时也得不到子集信息。

    因此,需要调用Chart里面proxy的writer来得到嵌套模型的json:

var writer = Arim.model.chart.Chart.getProxy().getWriter();
var data = writer.getRecordData(chartmodel);
var json = Ext.encode(data);

    读取时需要调用Chart里面proxy的reader来解析json得到嵌套模型:

var reader = Arim.model.chart.Chart.getProxy().getReader();
var model = reader.readRecords([json]).getRecords()[0];

  4.总结

    嵌套模型对于处理复杂业务对象很有用处,我们在生产中会把图形(本文中的例子)、报表等设计为模板,模板再encode为json字符串保存到后台,采用嵌套模型和相应的form代码逻辑简单清晰,通过reader、writer实现嵌套模型与json字符串之间的转换是其中的关键。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值