转:http://blog.csdn.net/walkerjong/article/details/7894845
最近项目中用到了Extjs,刚好碰到了一个问题就是数据模型的从属关系(association),就是我们常说的数据嵌套。本篇文章分两部分,第一部分讲解嵌套数据模型的定义;第二部分讲解嵌套数据模型的显示。
需求描述: 现在有一个项目,项目下有n个成员。
Project:
projectId, projectName, projectManager
ProjectMember
memberId, memberName, projectId
项目成员从属于项目,是 project hasMany member 的关系。
Extjs的Model定义如下:
/** * 项目成员model定义 */ Ext.define('ProjectMember', { extend: 'Ext.data.Model', fields: [{ name : 'memberId', //项目成员Id type : 'string' }, { name : 'memberName', //项目成员姓名 type : 'string' }, { name : 'projectId', //项目id type : 'string' }], belongsTo: { model : 'Project', primaryKey : 'memberId', foreignKey : 'projectId' } });
这里需要说明下belongsTo的属性定义:
model: 指定定义的model从属与哪一个model类型;
primaryKey: 定义的model中主键属性,若没有指定默认为id;
foreignKey: 定义的模型中从属模型的id,若没有定义则为"从属模型的小写名字_id",此处为"project_id";
更为详细的信息,可查询api获得。
Project在Extjs中的模型定义:
/** * 项目model定义 */ Ext.define('Project', { extend: 'Ext.data.Model', fields: [{ name : 'projectId', //项目id type : 'string' }, { name : 'projectName', //项目名称 type : 'string' }, { name : 'projectManager', //项目主管 type : 'string' }], hasMany: { model: 'ProjectMember', name: 'members', //访问member的方法 associationKey: 'memberList' //读取数据的property } });
这里需要说明下hasMany的属性定义:
model: 指定从属与它的模型名称,这里从属于项目的model是项目成员model;
name: 定义了访问从属成员的方法,若没有定义默认为从属model类型的复数(此处为projectmembers);
associationKey: 指定Reader读取数据的来源,即从数据中哪一个属性里取数据。若没有指定默认为name属性的值。
更为详细的信息,可查询api获得。
测试数据:
var testData = { "projects": [{ "projectId":"1", "projectName":"内存项目-1", "projectManager":"刘志远", "memberList":[{ "memberId": "FANGHJ", "memberName": "方浩江", "projectId" : "1" },{ "memberId":"ZHAOKUN", "memberName":"赵琨", "projectId" : "1" }] },{ "projectId":"2", "projectName":"内存项目-2", "projectManager":"刘志远", "memberList":[{ "memberId":"LIUFENG", "memberName":"刘凤", "projectId" : "2" },{ "memberId":"ZHAOKUN", "memberName":"赵琨", "projectId" : "2" }] },{ "projectId":"3", "projectName":"内存项目-3", "projectManager":"刘志远", "memberList":[{ "memberId": "FANGHJ", "memberName": "方浩江", "projectId" : "3" },{ "memberId":"ZHAOKUN", "memberName":"赵琨", "projectId" : "3" },{ "memberId":"CUILT", "memberName":"崔凌涛", "projectId" : "3" }] }], "totalCount":3 };
加载数据的store:
var projectStore = Ext.create('Ext.data.Store', { model: 'Project', pageSize: 10, proxy: { type: 'memory', data: testData, reader: { type: 'json', root: 'projects', totalProperty: 'totalCount' } } }); projectStore.load({ //数据加载完成后调用 callback: function(){ //遍历store的数据 projectStore.each(function(record){ document.write("projectId="+record.get("projectId")+", projectName="+record.get("projectName")+",projectManager="+record.get("projectManager")+"<br />"); var members = record.members(); document.write("members.size="+members.getCount()+"<br />"); members.each(function(record){ document.write("memberId="+record.get("memberId")+", memberName="+record.get("memberName")+", projectId="+record.get("projectId")+"<br />"); }); document.write("<br />"); return true; }); } });
完整的在页面里可运行的代码:
testModel.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title> New Document </title> <meta name="Generator" content="EditPlus"> <meta name="Author" content=""> <meta name="Keywords" content=""> <meta name="Description" content=""> <link rel="stylesheet" type="text/css" href="extjs/resources/css/ext-all.css" /> <script type="text/javascript" src="extjs/ext-all.js"></script> <script type="text/javascript"> Ext.onReady(function(){ /** * 项目成员model定义 */ Ext.define('ProjectMember', { extend: 'Ext.data.Model', fields: [{ name : 'memberId', //项目成员Id type : 'string' }, { name : 'memberName', //项目成员姓名 type : 'string' }, { name : 'projectId', //项目id type : 'string' }], belongsTo: { model : 'Project', primaryKey : 'memberId', foreignKey : 'projectId' } }); /** * 项目model定义 */ Ext.define('Project', { extend: 'Ext.data.Model', fields: [{ name : 'projectId', //项目id type : 'string' }, { name : 'projectName', //项目名称 type : 'string' }, { name : 'projectManager', //项目主管 type : 'string' }], hasMany: { model: 'ProjectMember', name: 'members', //访问member的方法 associationKey: 'memberList' //读取数据的property } }); var testData = { "projects": [{ "projectId":"1", "projectName":"内存项目-1", "projectManager":"刘志远", "memberList":[{ "memberId": "FANGHJ", "memberName": "方浩江", "projectId" : "1" },{ "memberId":"ZHAOKUN", "memberName":"赵琨", "projectId" : "1" }] },{ "projectId":"2", "projectName":"内存项目-2", "projectManager":"刘志远", "memberList":[{ "memberId":"LIUFENG", "memberName":"刘凤", "projectId" : "2" },{ "memberId":"ZHAOKUN", "memberName":"赵琨", "projectId" : "2" }] },{ "projectId":"3", "projectName":"内存项目-3", "projectManager":"刘志远", "memberList":[{ "memberId": "FANGHJ", "memberName": "方浩江", "projectId" : "3" },{ "memberId":"ZHAOKUN", "memberName":"赵琨", "projectId" : "3" },{ "memberId":"CUILT", "memberName":"崔凌涛", "projectId" : "3" }] }], "totalCount":3 }; var projectStore = Ext.create('Ext.data.Store', { model: 'Project', pageSize: 10, proxy: { type: 'memory', data: testData, reader: { type: 'json', root: 'projects', totalProperty: 'totalCount' } } }); projectStore.load({ //数据加载完成后调用 callback: function(){ //遍历store的数据 projectStore.each(function(record){ document.write("projectId="+record.get("projectId")+", projectName="+record.get("projectName")+",projectManager="+record.get("projectManager")+"<br />"); var members = record.members(); document.write("members.size="+members.getCount()+"<br />"); members.each(function(record){ document.write("memberId="+record.get("memberId")+", memberName="+record.get("memberName")+", projectId="+record.get("projectId")+"<br />"); }); document.write("<br />"); return true; }); } }); }); </script> </head> <body> </body> </html>
运行环境: Extjs 4.1.0
运行效果:如图
相关推荐
1. **ExtJS动态树(TreePanel)**: ExtJS TreePanel组件是用于显示和操作树形数据的控件。它支持多种特性,如拖放、分页、异步加载等。创建一个动态树,我们需要定义树节点的数据模型(TreeNode),配置数据源...
Model定义了数据的结构和规则,两者结合实现了数据的管理与展示。 5. **GridPanel**:ExtJS的GridPanel是展示大量结构化数据的理想选择。它支持分页、排序、过滤和编辑等功能,可以轻松地创建功能完备的数据表格。 ...
4. **Store与Model**: Store是数据存储的容器,可以与远程服务器进行数据交换,而Model定义了数据字段和行为,两者结合实现了数据的CRUD操作。 5. **Grid Panel**: Grid Panel是ExtJs中展示表格数据的重要组件,...
作为一款优秀的前端框架,ExtJS不仅在UI组件管理和风格统一方面表现出色,同时也引入了许多经典的设计模式,极大地提高了开发效率与代码质量。本文将重点围绕ExtJS中的几种主要设计模式进行详细介绍。 #### 组合...
- 属性值可以是任何数据类型,包括数组和嵌套的对象。 - 数组用方括号表示,可以包含各种元素,包括对象和值。 **表单字段与XType**: - `xtype` 用于定义字段类型,关联到EXTJS中的特定组件。例如,`textfield` ...
在IT行业中,前端和后端的协作是实现各种功能的关键,比如在本例中,我们需要在前端使用ExtJS,后端使用Java来实现一个导出Excel报表的功能。这个功能允许用户点击按钮后,系统生成一个Excel文件,包含了指定的数据...
Model用于管理数据,View负责显示数据,Controller协调Model和View的交互。这种设计模式让代码结构清晰,易于维护。 3. 源码解析 EXTJS 的源码组织有序,主要由JavaScript文件组成,包括类定义、扩展和配置。通过...
2. 创建Store:定义一个数据存储(Store),用于存放树形结构的数据。每个节点都是一个对象,包含id、text和children等属性,用于表示层级关系。 3. 创建TreePanel:创建一个TreePanel,作为下拉列表的基础。设置其...
- **数据管理**:了解 Extjs 中的数据管理机制,包括 DataProxy、DataReader 和 Store 类。 - **ComboBox**:深入探讨 ComboBox 的用法,这是一种常见的下拉列表框组件。 #### 十一、Ajax 与 ComboBox - **Ajax ...
在ExtJS中,Grid Panel是用于显示和编辑表格数据的组件。你可以通过配置store(存储数据)和column model(列模型)来创建表格。此外,通过启用编辑器,可以使单元格变为可编辑状态,实现数据的实时修改。这在处理...
在示例代码中,store的定义包含了字段定义,如'id', 'statTime', 'activeCount', 和 'effectiveCount',并且'statTime'字段被设置为日期类型,以便正确处理时间数据。 ```javascript var store = Ext.create('Ext....
- **代码**:定义图表类型和数据系列。 以上内容概述了Ext JS框架的主要组成部分及其实现方式。通过学习这些组件,开发者可以构建出既美观又实用的Web应用程序。Ext JS的强大之处在于其灵活性和扩展性,允许开发者...
总结,ExtJS 2.1中文帮助文档是学习和精通该框架的重要参考资料,它覆盖了主要组件的使用和源码解析,对于希望提升JavaScript前端开发技能的开发者来说,是一份不可或缺的学习材料。通过深入研究这些文档,开发者...
模型负责定义数据结构,商店管理一组模型实例,而代理则处理数据的加载和保存。 4. **高级布局(Layouts)**:EXTJS 4提供了一系列灵活的布局管理器,如表格布局、流式布局、绝对布局等,可以适应不同屏幕尺寸和...
EXTJS是一个广泛使用的JavaScript库,尤其在开发富客户端应用程序时,EXT-1.0是EXTJS的早期版本,它提供了丰富的组件和强大的数据管理功能。本文将深入EXT-1.0的源码,探讨其中的核心概念和技术,以及部分中文解读。...
- **GridPanel构造**:GridPanel是一种用于展示表格数据的容器,可以通过配置数据源和列模型来定制其展示方式。 - **数据源store**:GridPanel的数据来源于一个Store对象,该对象负责管理表格中的数据集。 - **列...
ExtJS是一个强大的JavaScript库,用于构建富客户端的Web应用程序,其核心特性包括数据绑定、组件化、布局管理等。这款主题以蓝色为主色调,旨在提供专业且现代的界面设计。 在深入探讨XTheme-Blue之前,我们需要...
本文将深入探讨"Ext常用属性总结"这一主题,帮助开发者更好地理解和利用ExtJS的特性。 首先,让我们了解几个基本的ExtJS概念。`Ext.Component`是所有UI组件的基础类,它拥有众多属性来控制组件的行为、外观和交互。...
数据模型定义了字段的类型和结构,存储器则负责加载和管理数据。接着,创建Grid Panel,并配置其column配置项,通过嵌套的Column对象来定义多级表头。分组表头可以通过设置`header`属性为一个包含子列的数组来实现。...