文档章节

extjs 5.0 mvvm模式

村长大神
 村长大神
发布于 2015/04/24 01:20
字数 2386
阅读 103
收藏 5
点赞 0
评论 0
目录页 :《 extjs5.0学习笔记

Ext JS提供了mvc和mvvm的应用程序框架支持,这两种架构方法都是关注于将应用程序代码和业务逻辑分离。每一种方法都有自己的优点,这取决于怎么分离应用程序模块。下面我们就简单看一下:

什么是MVC框架?
在一个MVC框架中,大多数的类要么是模型(model)要么是视图(view)要么是控制器(controller)。用户(user)与视图(view)交互,视图(view)呢又显示模型(model)中的数据(data)。这些交互都被控制器(controller)监控,控制器(controller)又在需要的时候通过更新模型(model)和视图(view)与响应交互。


什么是mvvm框架?

mvvm简单说来就是在MVC的基础上,新增了一个类似数据仓库的概念。就是说我有了数据模型(model),也有了视图展现(view),还有对其分发处理的控制器(controller)之后,多了一个储蓄所,如下图:



上面的三个模块就是传统的MVC模式,ExtJS在此基础上提供了VM模块。它发出请求,通过我们指定的模型来组装后返回,之后每次有数据请求时,都可以从这里获取数据,减少了服务器的请求次数。

层级结构关系

下面是ExtJS的MVVM框架的目录结构,对于不知道Extjs环境如何部署的朋友,可参考这篇文章《
Extjs5.0集成Eclipse 》。



这里能够很清楚的看到controller、model、store及view三个层次,也就是MVVM的分层目录。这种思想在ExtJS4.X中也有体现,但是在5.X之后添加了新的特性,就是viewmodel和viewcontroller:





这里的viewmodel就是MVVM中的VM,viewcontroller就是在原来controller基础上的演进,目的是实现了动态加载,防止一次性加载过多的js导致的数据阻塞的问题。





上图就展现了login文件夹下三个js文件的关系。Login.js是一个登陆窗体,调用的方法逻辑都在LoginController.js中,项目初始化的参数存储在LoginModel.js,各司其职,非常明了。

下篇就以一个登录的实例来介绍下ExtJS5.0中是如何实现的。


1、校验

对于最基本的校验当然是不能缺少的。这里的校验包括对空值、输入字段的长度及是否正确都进行了校验,
比如如下两图:




2、验证码刷新

如上图中验证码为 R8DR,点击后变为 0PSS
在后台对验证码进行了大小写处理,由于大些更容易辨认,所以在前台生成时用大些,输入的验证码大小写都是可以的。



3、重置与确定

点击重置后会将输入的内容清空



点击确定后则进入后台页面(目前还是比较丑陋的),这里利用session进行了限制,如果正常登陆后刷新页面是不会重新登陆的。




下一篇螃蟹就登陆的ExtJS代码进行详解,核心代码如下:



  1. Ext.define('app.view.login.Login', {
  2. extend: 'Ext.window.Window',
  3. requires: [
  4. 'app.view.login.LoginController',
  5. 'app.view.login.LoginModel',
  6. 'Ext.form.Panel',
  7. 'Ext.button.Button',
  8. 'Ext.form.field.Text',
  9. 'Ext.form.field.ComboBox'
  10. ],
  11. viewModel: 'login',
  12. controller: 'login',
  13. title: 'IT学习者-人事管理系统登陆',
  14. closable: false,
  15. width : 400,
  16. height : 230,
  17. cls: 'login',
  18. buttonAlign : 'center',
  19. items:[{
  20. xtype : "displayfield",
  21. value : "",
  22. height:30,
  23. margin : "0 0 0 0"
  24. },{
  25. layout : "column",
  26. items : [{
  27. columnWidth:.7,
  28. xtype: 'form',
  29. reference: 'form',
  30. defaults : {
  31. labelSeparator : ':',
  32. labelWidth : 60,
  33. width : 200,
  34. labelAlign : 'left'
  35. },
  36. defaultType : 'textfield',
  37. items : [ {
  38. xtype : 'textfield',
  39. fieldLabel : ' 用户名 ',
  40. emptyText:"请输入用户名",
  41. regex : /([A-Za-z]{1})\w{1,19}/,
  42. regexText : '用户名格式有误',
  43. name : 'loginName',
  44. allowBlank : false,
  45. blankText : '用户名不能为空',
  46. minLength : 5,
  47. minLengthText : '用户名的长度为[5-16]',
  48. maxLength : 16,
  49. maxLengthText : '用户名的长度为[5-16]',
  50. margin : "10 10 10 50"
  51. }, {
  52. xtype : 'textfield',
  53. name : 'password',
  54. inputType : 'password',
  55. fieldLabel : '密 码',
  56. fieldCls : 'password',
  57. emptyText:"请输入密码",
  58. inputType : 'password',
  59. allowBlank:false,
  60. blankText : '密码不能为空',
  61. minLength : 5,
  62. minLengthText : '密码的长度为[5-20]',
  63. maxLength : 20,
  64. maxLengthText : '密码的长度为[5-20]',
  65. margin : "15 10 10 50"
  66. },{
  67. xtype:'textfield',
  68. width:120,
  69. fieldLabel : '验证码',
  70. name : 'authcode',
  71. allowBlank:false,
  72. blankText : '验证码不能为空',
  73. margin : "15 0 0 50"
  74. },{
  75. xtype:'panel',
  76. columnWidth:.4,
  77. height:30,
  78. html:"<a href='#' onclick='javascript:refreshCode();'><img id='validateCodeImg' title='点击更换' alt='点击更换' src='authCode' /></a>",
  79. margin : "-26 0 175"
  80. }]
  81. },{
  82. layout:'fit',
  83. bodyStyle: 'background:transparent',//设置为透明,不不妨碍更换主题了
  84. columnWidth:.28,
  85. height:120,
  86. items:[{
  87. xtype : "displayfield",
  88. hideLabel : true,
  89. margin : "-105 0 0 0",
  90. value : "<img src='./images/itxxz.png' />"
  91. }]
  92. }]
  93. }],
  94. buttons: [{
  95. text: '确定',
  96. listeners: {
  97. click: 'onLoginClick'
  98. }
  99. },{
  100. text: "重置",
  101. handler: function () {
  102. this.up('window').down('form').getForm().reset();
  103. }
  104. }]
  105. });
  106. //刷新验证码
  107. function refreshCode() {
  108. document.getElementById("validateCodeImg").src = "authCode?"+Math.random();
  109. }

刚开始学习的时候,螃蟹也是一头雾水,但是由于ExtJS5.0的书写及其规范,API相当完整,于是,在学习的时候螃蟹尽量的不脱离其设计思想,在原有的框架基础上进行开发改进。

比如我们定义一个类,就可以通过以下的语法进行定义:

  1. Ext.define('TextClass', {
  2. name: 'itxxz',
  3. value: 'IT学习者'
  4. });



这样,我们就定义了一个TextClass的类,这个类里有name和value两个属性,以后使用的时候,直接new或者Create就可以了。

就好比上篇中我们定义了登陆窗口,

  1. Ext.define('app.view.login.Login', {..}



这里的定义就与TextClass的定义不同了,学过java的朋友可能更好理解一些,这里的 app.view.login.Login 其实就是一个文件的路径,而app并非如下图的根路径,而是我们定义的命名空间,具体的定义规则在《Extjs5.0集成Eclipse》中的sencha命令已有介绍。

那么
view.login.Login就是文件的路径了,比如我们的登陆窗口是定义的Login.js文件,那么定义这个类的时候,规则就是命名空间加上路径最后以类的名字结尾,这样就可以找到该文件了,就好比我们定义app.view.login.Login一样,如下图:





这时候问题就来了,如果我们想定义一个window窗口,该如何下手?

在ExtJS中也引入了集成的思想,这样就避免了我们重复发明轮子的烦恼,想实现什么,只要extend一下就可以了:

  1. extend: 'Ext.window.Window',



在我们平常写js的时候往往会有很多js的引入来相互配合,这在ExtJS中也有体现,就是通过require来实现:

  1. requires: [
  2. 'app.view.login.LoginController',
  3. 'app.view.login.LoginModel',
  4. 'Ext.form.Panel',
  5. 'Ext.button.Button',
  6. 'Ext.form.field.Text',
  7. 'Ext.form.field.ComboBox'
  8. ],


这是我们需要的js文件,通过本篇讲解的类的定义规则,相信应该可以看懂这种命名规范了。

下面我们来看一下特殊的写法:

  1. viewModel: 'login',
  2. controller: 'login',


这里是引用viewModel和controller,有关这方面的介绍可看一下《ExtJS5.0的mvvm分层思想》。

通过上图中可以看到,login文件夹下一共定义了三个文件:Login.js、LoginController.js、LoginModel.js 。

Login.js的代码在上一篇已经张贴了出来,下面先简单看下另外的代码:

LoginController.js

  1. Ext.define('app.view.login.LoginController', {
  2. extend: 'Ext.app.ViewController',
  3. alias: 'controller.login',
  4. loginText: 'Logging in...',
  5. constructor: function () {
  6. this.callParent(arguments);
  7. this.loginManager = new app.LoginManager({});
  8. },
  9. onSpecialKey: function(field, e) {
  10. if (e.getKey() === e.ENTER) {
  11. this.doLogin();
  12. }
  13. },
  14. onLoginClick: function() {
  15. this.doLogin();
  16. },
  17. doLogin: function() {
  18. var form = this.lookupReference('form');
  19. if (form.isValid()) {
  20. Ext.getBody().mask(this.loginText);
  21. this.loginManager.login({
  22. data: form.getValues(),
  23. scope: this,
  24. success: 'onLoginSuccess',
  25. failure: 'onLoginFailure'
  26. });
  27. }
  28. },
  29. onLoginFailure: function() {
  30. Ext.getBody().unmask();
  31. },
  32. onLoginSuccess: function() {
  33. Ext.getBody().unmask();
  34. this.fireViewEvent('login', this.getView(), null, null, this.loginManager);
  35. }
  36. });


LoginModel.js

  1. Ext.define('app.view.login.LoginModel', {
  2. extend: 'Ext.app.ViewModel',
  3. alias: 'viewmodel.login',
  4. // Just some data to seed the process. This might be pulled from a cookie or other
  5. // in a real app.
  6. data: {
  7. defaultOrg: 1,
  8. username: 'IT学习者-螃蟹'
  9. }
  10. });


在上面两贴代码的第三行,都有一个alias属性,它的作用就是为该类起一个别名,用过数据库的朋友对此应该不陌生。

这样再回头看这两行代码应该知文识意了,没错,就是根据别名来引用的。

  1. viewModel: 'login',
  2. controller: 'login',


在这样引用后,ExtJS会默认生成这两个文件的对象了。

这篇就先介绍类的定义继承及引用,下篇我们继续分析

 

在前几篇的教程中,螃蟹已经简单介绍了Extjs如何加载java后台的数据,不过是以项目中所定义的规范加载的,鉴于不少朋友依旧咨询这方面的问题,这里就以store为例,单独说明一下

这是用于加载数据的请求,有些类似ajax,指定请求的url,请求的字段属性,也就是fields中定义的属性,再一个就是要指定根节点root


  1. var store_itxxz = Ext.create('Ext.data.Store', {  
  2.                 storeId:'simpsonsStore',  
  3.                 fields:['empid''userName''sex'],  
  4.                 proxy: {  
  5.                     type: 'ajax',  
  6.                     url: 'emp/queryAll',  
  7.                     reader: {  
  8.                         type: 'json',  
  9.                         root: 'data'  
  10.                     }  
  11.                 },  
  12.                 autoLoad: true  
  13.             });  


然后就是如何调用的问题

  1. var grid = Ext.create('Ext.grid.Panel', {  
  2.                 title: 'Simpsons',  
  3.                 store: store_itxxz,  
  4.                 columns: [  
  5.                     {header: '登录名',  dataIndex: 'userName'},  
  6.                     {header: 'empid', dataIndex: 'empid', flex:1}  
  7.                 ],  
  8.                 dockedItems: [{  
  9.                     xtype: 'pagingtoolbar',  
  10.                     store: store_itxxz,   // GridPanel使用相同的数据源  
  11.                     dock: 'bottom',  
  12.                     displayInfo: true  
  13.                 }]  
  14.             });  


这里第3行和第10行的store:store_itxxz中,左边的store是指grid中定义的数据源属性,右边的store_itxxz是指我们数据对象。

第10行是用来加载列表的数据,做显示用,第10行为分页用。

java后台代码:


  1. /** 
  2.  * 员工列表 
  3.  * @return  
  4.  * @throws Exception 
  5.  */  
  6. @RequestMapping("/queryAll")  
  7. @ResponseBody  
  8. public Map<String,List<Employee>> queryAllEmps() throws Exception{  
  9.     log.info("员工列表");  
  10.     List<Employee> allList = employeeService.selectAllEmps();  
  11.     Map<String,List<Employee>> map = new HashMap<String,List<Employee>>();  
  12.     map.put("data", allList);  
  13.     System.out.println(map);  
  14.     return map;  
  15. }  


后台代码中返回的是一个map,以ajax形式返回,是SpringMVC的基本用法,这里就不多介绍了。

第12行,map中put了一个key为data,value为allList的元素,这里的data就是store_itxxz中的root指定的根节点。

也可以修改一下,比如根节点叫做itxxz_data,那么再此处只需要将key改为itxxz_data,store_itxxz中奖root的定义data也改为itxxz_data就可以了。

数据的返回格式如下:


{ data: [ {empid: '001', userName:'IT学习者', sex:'男'}, {empid: '002', userNmae:'螃蟹', sex:'女'}  ] }


效果图可参考《Extjs5.0 GridPanel数据动态加载

 


 

 

本文转载自:http://www.itxxz.com/a/gaoji/2015/0119/556.html

共有 人打赏支持
村长大神
粉丝 162
博文 876
码字总数 904789
作品 0
杭州
程序员
Extjs MVC开发模式详解

在JS的开发过程中,大规模的JS脚本难以组织和维护,这一直是困扰前端开发人员的头等问题。Extjs为了解决这种问题,在Extjs 4.x版本中引入了MVC开发模式,开始将一个JS(Extjs)应用程序分割成...

鱼煎
2017/11/02
0
0
ExtJs4.1目录结构介绍和使用说明

一、在做ExtJs开发之前首先要到网站上下载ExtJs的开发包,我用的最新版本是4.1.1。此版本相对于之前的版本目录结构发生了一些变化,没有了adapter目录, 目录结构如下 文件/文件夹名的作用:...

Junn
2013/01/17
0
1
ExtJS开发环境的搭建,spket工具安装详解

集成:ExtJS,MyEcplise和Spket。 前提:安装好的myecplise(我用的是MyEcplise10) 步骤: 先安装Spket 1 下载Spket的jar文件,spket-1.6.18.jar 2 将jar文件解压到MyEcplise的dropins文件夹...

day戴
2014/09/04
0
0
Eclipse开发Javascript环境配置(含EXTJs配置) 转载

有三种Javascript编辑器可供选择: 1. JSDT 2. JSEclipse 3. Spket 分别介绍这三种插件的安装: 1. JSDT 是WPT自带的插件 只要装了WTP就不用单独安装JSDT了。也可以从这里了解JSDT的一些信息...

晨曦之光
2012/03/24
0
0
Extjs GridPanel用法详解

创建GridPanel 要使用GridPanel,首先要定义Store,而在创建Store的时候必须要有Model,因此我们首先来定义Model: //1.定义ModelExt.define("MyApp.model.User", { }); 然后创建Store: //...

鱼煎
2017/11/02
0
0
Extjs Window用法详解

创建Extjs Window 创建Extjs Window的代码如下: //创建windowvar win = Ext.create("Ext.window.Window", { }); 代码中的Form可以参考《Extjs Form用法详解》。显示效果如下: 显示Extjs W...

鱼煎
2017/11/02
0
0
ExtJS中get、getDom、getCmp、getBody、getDoc的使用

Ext中包含了几个以get开头的方法,这些方法可以用来得到文档中DOM、得到当前文档中的组件、得到Ext元素等,在使用中要注意区别使用。 1、get方法 get方法用来得到一个Ext元素,也就是类型为E...

Junn
2012/11/22
0
0
ExtJS4.2学习 php版(六)

ExtJS Ext.data.proxy.Memory //定义模型Ext.define('User', { extend: 'Ext.data.Model', fields: [ {name: 'id', type: 'int'}, {name: 'name', type: 'string'}, {name: 'phone', type: '......

lbc19920615
2014/04/03
0
0
ExtJs自学教程(1):一切从API开始

该系列文章不侧重全方位的去介绍ExtJs的使用,只是侧重于解决ExtJs问题的思考方法。写的人不用长篇大论,学的人则能够自立更生。l 学习的人只要有一些CSS的javascript的基础知识并且对于英文...

77970290
2013/05/07
0
0
为Zend Studio (Eclipse)安装Spket插件,以支持ExtJS 4.0代码自动提示

之前在Zend Studio 7.0中安装过ExtJS2.0的自动提示,现在的软件升级太快,ExtJS4.0都出来了,无奈选择升级,不升还好,这一升搞了我半天的时间,怎么弄都 没提示了,干啥都得花点时间就好比这...

BabyMason
2015/02/06
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Git 修改提交的用户名和邮箱名字

在通过git提交代码时,发现提交的用户名是自己mac的账户名,想要修改为其他名字和邮箱。 相关命令是: git 修改当前的project的用户名的命令为: git config user.name 你的目标用户名 git修...

edwardGe
2分钟前
0
0
Object.defineProperty()

Object.defineProperty()方法直接在一个对象上定义新的属性或修改现有属性,并返回该对象。 其中的get和set是vue双向绑定的原理

litCabbage
3分钟前
0
0
JEESZ分布式框架--单点登录集成方案(三)

多项目集成单点登录配置 当sso验证完成之后,客户端系统需要接收sso系统返回的结果时,需要定义一个过滤器获取返回结果,然后针对返回结果做相关处理.如果不需要做处理时,此处Filter也可以不...

明理萝
3分钟前
0
1
plisteditor 查看ipa包名及其它信息

1.下载ipa安装包 2.用rar等工具打开 3.将iTunesMetadata.plist文件解压出来 4.用plist Editor 工具打开 或http://www.atool.org/plist_reader.php在线反编译工具 5.在其中中找到softwareVer...

xiaogg
4分钟前
0
0
spring retry 小试

retry就是重试的意思,在我们的系统中,分布式或者是外部服务,存在其他服务异常,或者网络问题,需要我们重试的情况,但是重试可能还是错误的,总不能让系统一直报错,直到崩掉吧。所以熔断...

woshixin
7分钟前
0
0
【易错】一级缓存、二级缓存介绍与常见问题(四)

一般来说,可以在5个方面进行缓存的设计: 1.最底层可以配置的是mysql自带的query cache, 2.mybatis的一级缓存,默认情况下都处于开启状态,只能使用自带的PerpetualCache,无法配置第三方缓...

大白来袭
16分钟前
0
0
rancher安装kubernetes

参考https://rancher.com/quick-start/ 环境(必须相同。否则有很多问题): Ubuntu 16.04 Docker versions are 1.12.6, 1.13.1 or 17.03.2 1、docker安装https://docs.docker.com/install/l......

杰仪
16分钟前
0
0
几维安全Javascript代码混淆(js加密)在线使用说明

几维安全Javascript代码混淆是一项在线加密服务,用户只需将JS文件打包成zip包,提交到加密平台,即可完成代码混淆、字符串加密、属性加密、调用转换等多项保护措施,提高攻击者分析Javascr...

工作的事
18分钟前
1
0
解决dokuwiki创建中文词条文件乱码问题

若直接创建中文词条,打开本地文件夹\dokuwiki\data\pages你会发现,中文字段显示的是URL乱码,需要改一下utf8格式,方法如下:(linux系统亲测有效) 打开 .dokuwiki\conf\local.php 添加一行...

Rhymo-Wu
21分钟前
0
0
设置圆角长条progressbar背景色

1、首先在Drawable下面新建一个xml文件,将这段代码复制进去 <?xml version="1.0" encoding="utf-8"?><layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <!-......

王先森oO
21分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部