我们在上一节中介绍了如何在ExtJS 中自定义类,这一节中将介绍如何自定义数据模型。

自定义数据模型

在上一节中,我们使用Ext.define 来自定义类,通过Ext.define 定义的类都默认继承自Ext.base 类。如果我们将extend 设置为Ext.data.Model,那么定义的类就是一个数据模型类了。先定义一个简单的数据模型类 User类,代码如下:

  1. Ext.define('MyApp.User', {
  2. extend: 'Ext.data.Model',
  3. fields: [
  4. { name: 'name', type: 'string' },
  5. { name: 'age', type: 'int' },
  6. { name: 'phone', type: 'string' }
  7. ]
  8. });

在代码中可以看出,数据模型类其实就是一个继承自Ext.data.Model 的类。

fields 属性中定义了该模型的字段,它可以是对应到数据库中的字段。在使用的时候,数据模型包含的字段和类的属性使用方式不太相同。要访问字段的值,需要视同get 和 set 方法,例如:

  1. var Tom = Ext.create("MyApp.User", {
  2. name: 'Tom',
  3. age: 26,
  4. phone:'123456'
  5. });
  6. Tom.set('age', 20);
  7. Ext.MessageBox.alert('提示', Tom.get('age'));

我们实例化User类,初始化的时候,age的值为26,然后通过set 方法设置为 20,再通过get 方法得到 age 字段的值,运行截图如下:

字段类型和转换器

在定义数据模型的时候,我们可以定义字段的类型和该类型的转换器。例如,我们将为User类添加birthday字段,在初始化的时候,我们可能会传入一个字符串类型的日期格式,这个时侯就需要我们来定义一个类型转换器,将字符串格式的日期转换为Date类型。代码如下:

  1. Ext.define('MyApp.User', {
  2. extend: 'Ext.data.Model',
  3. fields: [
  4. { name: 'name', type: 'string' },
  5. { name: 'age', type: 'int' },
  6. { name: 'phone', type: 'string' },
  7. {
  8. name: 'birthday',
  9. type: 'date',
  10. convert: function

(value, record) { if (Ext.isDate(value)) return value; else if (Ext.isString(value)) { return Ext.Date.parse(value, "Y-m-d"

  1. );
  2. }
  3. }
  4. }
  5. ]
  6. });

在代码中添加了birthday字段,并为该字段设置了转换器,当传入的类型为string时,将会被转换为标准的时间类型。用法如下:

  1. var Tom = Ext.create("MyApp.User", {
  2. name: 'Tom',
  3. age: 26,
  4. phone: '123456',
  5. birthday:'2000-01-15'
  6. });
  7. alert(Tom.get('birthday'));

在使用的时候,传入的是一个字符串类型的时间,当我们实例化以后,字符串日期被转换为标准的时间类型:

数据验证

我们可以使用数据模型来验证数据是否正确。在上面的例子中,我们希望phone 字段的长度在8和15之间,那么,我们需要这样修改代码:

  1. Ext.define('MyApp.User', {
  2. extend: 'Ext.data.Model',
  3. fields: [
  4. { name: 'name', type: 'string' },
  5. { name: 'age', type: 'int' },
  6. { name: 'phone', type: 'string' },
  7. {
  8. name: 'birthday',
  9. type: 'date',
  10. convert: function (value, record) {
  11. if (Ext.isDate(value))
  12. return value;
  13. else if (Ext.isString(value)) {
  14. return Ext.Date.parse(value, "Y-m-d");
  15. }
  16. }
  17. }
  18. ],
  19. validations: [
  20. { field:

'phone', type: 'length'

  1. , min: 8, max: 15 }
  2. ]
  3. });

为phone 字段添加验证,验证类型为length,最小为8,最大为15,验证的代码如下:

  1. var Tom = Ext.create("MyApp.User", {
  2. name: 'Tom',
  3. age: 26,
  4. phone: '123456',
  5. birthday:'2000-01-15'
  6. });
  7. var errors = Tom.validate();
  8. var errorMsg = [];
  9. if (!errors.isValid()) {
  10. errors.each(function (error) {
  11. errorMsg.push(error.field + " " + error.message);
  12. });
  13. Ext.Msg.alert("错误", errorMsg.join('<br />'));
  14. }

我们将phone的长度设置为6位,很明显是不能通过验证的。程序运行起来以后,我们会得到下面的错误:

尽管我们已经引入了汉化包,但这里的提示还是英文的,为了能让他显示为中文,我们需要手动的来将其汉化,在程序开始的时候加入代码:

  1. Ext.data.validations.lengthMessage = "长度错误";

刷新我们的页面,错误提示已经变成中文了:

由此可以看出,ExtJS 的验证错误提示是没有进行汉化的,我们可以将相应的汉化代码写在Layout中,方便所有页面都能够使用。

自定义验证规则

ExtJS 中虽然内置了一些验证规则,但这些规则面对庞大的业务需求肯定是不够的,所以ExtJS 还允许我们自定义验证规则。

在User类中,我们希望age字段的值在0到150之间,我们来自定义一个验证规则:

  1. Ext.apply(Ext.data.validations, {
  2. ageMessage: '必须在0到150之间',
  3. age: function (config, value) {
  4. if (value === undefined || value === null) {
  5. return false;
  6. }
  7.  
  8. if (value < 0 || value > 150) {
  9. return false;
  10. }
  11.  
  12. return true;
  13. }
  14. });

Ext.apply 方法用来将第二个参数中的属性和方法复制到第一个参数中,在这里的作用是将我们定义的age规则添加到Ext 的验证规则中。

接下来我们修改验证部分的代码,添加age验证:

  1. validations: [
  2. { field: 'phone', type: 'length', min: 8, max: 15 },
  3. { field: 'age', type: 'age', min: 8, max: 15 }
  4. ]

在初始化的时候,我们将age的值设置为-26,运行程序,截图如下:

数据模型之间的关系

(本段内容翻译自官方api)

模型之间可以通过 Ext.data.association.HasOne, belongsTo 和 hasMany 设置彼此的关系。例如在博客管理程序中,我们需要处理用户(Users)、文章(Posts)和评论(Comments)之间的关系,他们的关系如下:

  1. Ext.define('Post', {
  2. extend: 'Ext.data.Model',
  3. fields: ['id', 'user_id'],
  4.  
  5. belongsTo: 'User',
  6. hasMany: { model: 'Comment', name: 'comments' }
  7. });
  8.  
  9. Ext.define('Comment', {
  10. extend: 'Ext.data.Model',
  11. fields: ['id', 'user_id', 'post_id'],
  12.  
  13. belongsTo: 'Post'
  14. });
  15.  
  16. Ext.define('User', {
  17. extend: 'Ext.data.Model',
  18. fields: ['id'],
  19.  
  20. hasMany: [
  21. 'Post',
  22. { model: 'Comment', name: 'comments' }
  23. ]
  24. });

你可以通过查看API来了解更多的用法,另外,他们之间的关系还可以这样定义:

  1. Ext.define('User', {
  2. extend: 'Ext.data.Model',
  3. fields: ['id'],
  4.  
  5. associations: [
  6. { type: 'hasMany', model: 'Post', name: 'posts' },
  7. { type: 'hasMany', model: 'Comment', name: 'comments' }
  8. ]
  9. });

ExtJS 4.2 教程-04:数据模型的更多相关文章

  1. [译]Vulkan教程(04)基础代码

    [译]Vulkan教程(04)基础代码 General structure 通用结构 In the previous chapter you've created a Vulkan project w ...

  2. 【GStreamer开发】GStreamer播放教程04——既看式流

    目的 在<GStreamer基础教程--流>里面我们展示了如何在较差的网络条件下使用缓冲这个机制来提升用户体验.本教程在<GStreamer基础教程--流>的基础上在扩展了一下 ...

  3. ExtJS入门教程04,这是一个超级好用的grid

    今天进行extjs入门教程的第四篇:grid. 来一份grid尝尝 小伙伴们都知道extjs的grid功能强大,更清楚功能强大的东西用起来必然会复杂.今天我们就从最简单的grid开始讲解. 先来一个最 ...

  4. Extjs学习笔记之九 数据模型(上)-extjs

    来源:niutuku.com | vincent上传于2012-07-20 | 1802次浏览 | 0条评论 本文开始进入Extjs最核心最优秀的部分. 标签:Extjs 数据模型   Extjs的数 ...

  5. ExtJS 4.2 教程-03:使用Ext.define自定义类

    转载自起飞网,原文地址:http://www.qeefee.com/extjs-course-3-define-classes ExtJS 4.2 教程-01:Hello ExtJS ExtJS 4. ...

  6. ExtJS 4.2 教程-01:Hello ExtJS

    转载自起飞网,原文地址:http://www.qeefee.com/extjs-course-1-hello-extjs, 本文还发布在了ExtJS教程网站起飞网上面,如果转载请保留本段声明,谢谢合作 ...

  7. Android快乐贪吃蛇游戏实战项目开发教程-04虚拟方向键(三)三角形按钮效果

    该系列教程概述与目录:http://www.cnblogs.com/chengyujia/p/5787111.html 一.知识点讲解 当我们点击系统自带的按钮时,按钮的外观会发生变化.上篇博文中我们 ...

  8. Node.js 教程 04 - 模块系统

    前言: Node.js的模块系统类似于C/C++的文件引用,可以声明对象,也可以定义类 创建对象. 大家这么理解,就简单了. 定义: 为了让Node.js的文件可以相互调用,Node.js提供了一个简 ...

  9. Web前端性能优化教程04:压缩组件

    本文是Web前端性能优化系列文章中的第四篇,主要讲述内容:压缩组件.完整教程可查看:Web前端性能优化 基础知识 gzip编码:gzip是GUNzip的缩写,是使用无损压缩算法的一种,最早是用于Uni ...

随机推荐

  1. js里size和length的区别

    length: length是js的原生方法,用于获取元素的个数和对象的长度 var length = $(obj).length; size(): size()属于方法,只能作用于对象上,获取元素的 ...

  2. 使用GIT管理UE4代码

    在OSCHINA的GIT上创建远程项目 cd existing_git_repo git init git add Onepass/ Source/ notes.txt git commit -m & ...

  3. 【LOJ】#2082. 「JSOI2016」炸弹攻击 2

    题解 想到n3发现思路有点卡住了 对于每个发射塔把激光塔和敌人按照极角排序,对于一个激光塔,和它转角不超过pi的激光塔中间夹的敌人总和就是答案 记录前缀和,用two-Points扫一下就行 代码 #i ...

  4. Codeforces Round #480 (Div. 2) E - The Number Games

    题目大意:给你n个点的一棵树, 每个点的权值为2^i ,让你删掉k个点使得剩下的权值和最大. 思路:这题还是比较好想的, 我们反过来考虑, 剩下一个的情况肯定是选第n个点,剩下两个 我们肯定优先考虑第 ...

  5. django 的用户验证及登录状态保持

    一.用户验证功能 Django自带用户验证及登录功能,引入模块为: from django.contrib.auth import authenticate 其中方法authenticate()的接收 ...

  6. 谈 JavaScript 中的强制类型转换 (2. 应用篇)

    这一部分内容是承接上一篇的, 建议先阅读谈 JavaScript 中的强制类型转换 (1. 基础篇) 前两章讨论了基本数据类型和基本包装类型的关系, 以及两个在类型转换中十分重要的方法: valueO ...

  7. springmvc配置MappingJackson2HttpMessageConverter实现属性驼峰和下划线的转换

    需求 php调用java接口时,因为php那边的属性都是下划线风格,java这边的属性都是驼峰的风格.配置springmvc的json转换,在requestBody的时候(调用对象的set 方法)将j ...

  8. 命令:mktemp

    简介 mktemp命令用于创建一个临时的文件或者目录. 语法格式 mktemp [OPTION]... [TEMPLATE] 示例 不带选项和参数的mktemp用于创建临时文件,带-d选项用于创建临时 ...

  9. 【Ray Tracing in One Weekend 超详解】 光线追踪1-8 自定义相机设计

    今天,我们来学习如何设计自定义位置的相机 ready 我们只需要了解我们之前的坐标体系,或者说是相机位置 先看效果   Chapter10:Positionable camera 这一章我们直接用概念 ...

  10. shell 父子传值

    通过一个中间文件进行: #!/bin/bash   (  subvar="hello shell"  echo "$subvar" > temp.txt ...