原文:Building Maintainable Controllers in Ext JS Apps

在eMortgage Logic公司,2011年底开始使用Ext JS 4。当时,还不知道如何正确编写Ext JS应用程序,但最后还是掌握了如何让应用程序实现所需的方法。不过,这并不意味着能很好的去实现他们。最终结果是,应用程序是由十几个大规模控制器实现 处理的,而同时,视图使用的是一组简单的配置。控制器掌控着一切,但随着时间的推移,控制器变得越来越难于维护,这就让人开始怀疑当初的代码是否妥当了。

最后,我们试图让视图变得聪明一点,沿着这个思路,我们有点开窍了。最终,终于知道如何在控制器和视图之间划清界线了。为了说明我们团队新发现的这 个知识,我撰写了以下这个指南。该指南使用了一个简单的方式来说明如何拆卸大的控制器并替换他们的的逻辑代码,以便于维护。这不仅有利于短期内使用Ext JS 4的团队,也有利于近期升级到Ext JS 5视图控制器的团队。

在这篇文章,将创建一个小型的控制和有几个需求的简单视图,然后通过几个步骤来分离他们。

本文最终的目标是创建一个实现以下要求的控制器和视图:

  • 提供一个表单让用户输入喜好

  • 保持喜好到用户的记录

  • 更新用户的名字和喜好等信息

你好,“You Had Me”

查看相关代码

创建的视图将允许当前用户去查看和更新他们的爱好,该视图将使用build方法,因此后续工作会很简单。

app/view/Hobby.js

Ext.define('Example.view.Hobby', {extend: 'Ext.form.Panel',alias: 'widget.hobbyview',initComponent: function () {var me = this;me.items = me.buildItems();me.callParent(arguments);},buildItems: function () {return [{xtype: 'textfield',name: 'FavoriteHobby'},{xtype: 'button',itemId: 'save',text: 'Save'},{xtype: 'component',itemId: 'hobbyTpl',tpl: '{Name}\'s favorite hobby is {FavoriteHobby}'}];}
});1234567891011121314151617181920212223242526272829

下面,将创建控制器来管理视图:

app/controller/Hobby.js

Ext.define('Example.controller.Hobby', {extend: 'Ext.app.Controller',init: function () {this.control({            'hobbyview button#save': {click: this.onSaveButtonClick}});},onSaveButtonClick: function (button) {var form = button.up('form'),values = form.getValues(),user;        // We will assume the application provides a way to get the currently logged-in user.user = this.getApplication().getCurrentUser();user.set(values);user.save();form.down('#hobbyTpl').update({Name: user.get('Name'),FavoriteHobby: values.FavoriteHobby});}
});1234567891011121314151617181920212223242526

尽管是一个非常简单的控制器,但它知道视图对它有意见。

控制器要知道:

视图有一个ItemId为save的按钮
按钮是表单的一个子组件
如何从视图的表单中获得值
表单有一个itemId为hobbyTpl的子组件,如何去更新它?
表单不知道用户这个概念

控制器的一切完全依赖于视图的保存按钮和视图自身的结构,这将导致控制器和视图必须紧密耦合,譬如,如果保存按钮在表单组件的之外,控制器就不得不 重写。另外,如果itemId为hobbyTpl的组件被改变,控制器也需要进行相应的更改。视图中的任何微小变化都可能会令控制器出现问题。

你是Tearing Me Apart

查看相关代码

现在,你可以已经意识到控制器的一些问题了,下面就来解决这些问题。首先是要让视图与用户关联。

app/view/Hobby.js

Ext.define('Example.view.Hobby', {    // ...bindUser: function (record) {this.userRecord = record;},getUser: function () {return this.userRecord;}    // ...});1234567891011

通过设置一些方法来关联用户,这样就可以很容易的调整视图方法而不需要修改控制器。通过这些附加项,就可以通过传递一个实例或稍后调用bindUser方法后让视图关注用户记录。这样,还可以获取绑定的用户,而控制器则无须了解太多。

接下来,要让控制器允许视图去管理用户记录并更新数据。

app/controller/Hobby.js

Ext.define('Example.controller.Hobby', {    // ...onSaveButtonClick: function (button) {var form = button.up('form'),values = form.getValues(),user = form.getUser();user.set(values);user.save();form.down('#hobbyTpl').update({Name: user.get('Name'),FavoriteHobby: values.FavoriteHobby});}
});12345678910111213141516

很不错了,不过清单里还有一件事没做,那就是控制器还是要了解视图的结构,现在要做的就是让它更灵活。

下面更新一下清单:

控制器知道

  • 视图有一个ItemId为save的按钮

  • 按钮是表单的一个子组件

  • 如何从视图的表单中获得值

  • 表单有一个itemId为hobbyTpl的子组件,如何去更新它?

  • 表单不知道用户这个概念

模板?We Don’t Need [to be aware of] No Stinkin的模板

查看相关代码

视图一直很想知道为什么控制器不能专注于自己的商业逻辑,而这可通过移除模板的相关内容来让它少管点闲事。

视图希望它的模板在保存按钮被单击时被更新,为了实现这个目标,需要添加事件处理。

app/view/Hobby.js

Ext.define('Example.view.Hobby', {    // ...onSaveClick: function () {var me = this,values = me.getValues(),user = me.getUser();me.down('#hobbyTpl').update({Name: user.get('Name'),FavoriteHobby: values.FavoriteHobby});},buildItems: function () {var me = this;        return [{xtype: 'textfield',name: 'FavoriteHobby'},{xtype: 'button',itemId: 'save',text: 'Save',listeners: {click: me.onSaveClick,scope: me}},{xtype: 'component',itemId: 'hobbyTpl',tpl: '{Name}\'s favorite hobby is {FavoriteHobby}'}];}
});12345678910111213141516171819202122232425262728293031323334353637

现在,视图将处理更多的视图事务,而控制器也可以更简单了。

app/controller/Hobby.js

Ext.define('Example.controller.Hobby', {    // ...onSaveButtonClick: function (button) {var form = button.up('form'),values = form.getValues(),user = form.getUser();user.set(values);user.save();}
});1234567891011

不幸的是,控制器还是能看到不少的视图组件,不过至少列表中的事情又少了一件:

控制器知道

  • 视图有一个ItemId为save的按钮

  • 按钮是表单的一个子组件

  • 如何从视图的表单中获得值

  • 表单有一个itemId为hobbyTpl的子组件,如何去更新它?

  • 表单不知道用户这个概念

What We’ve Got Here是一个失败的沟通者

查看相关代码

现在一举解决余下的问题的时候了,这需要通过事件来实现视图与控制器之间的沟通。控制器只需要知道视图要获取数据,并且需要保存数据。

在onSaveClick事件中,视图中已经聚集了控制器所需的所有数据,因此这里只需要从这里出发一个事件。

app/view/Hobby.js

Ext.define('Example.view.Hobby', {    // ...onSaveClick: function () {var me = this,values = me.getValues(),user = me.getUser();me.fireEvent('save', me, values, user);me.down('#hobbyTpl').update({Name: user.get('Name'),FavoriteHobby: values.FavoriteHobby});},    // ...});12345678910111213141516

这小小的改变就可以让控制器变得足够简单,它只需要知道视图的存在,并会触发一个save事件。

app/controller/Hobby.js

Ext.define('Example.controller.Hobby', {extend: 'Ext.app.Controller',init: function () {this.control({            'hobbyview': {save: this.onSave}});},onSave: function (view, values, user) {user.set(values);user.save();}
});1234567891011121314

现在,控制器终于不需要再了解视图的结构了。控制器只保存数据,而是他只显示数据。

只要视图一直保持触发save时间,现在就不需要大量修改控制器了。

控制器知道

  • 视图有一个ItemId为save的按钮

  • 按钮是表单的一个子组件

  • 如何从视图的表单中获得值

  • 表单有一个itemId为hobbyTpl的子组件,如何去更新它?

  • 表单不知道用户这个概念

聪明的视图是重点且易于维护和测试

了解如何拆卸猛犸级的控制器对于团队更好的管理类来说是相当有帮助的。不但是控制器,视图也变得更集中和易于维护,他们也易于测试,而这也更接近于Ext JS视图控制器的功能。让视图变得更聪明还便于应用程序重用他们。

要知道的是:

  • 视图完全有能力管理自己的数据

  • 控制器应该以不了解视图内部结构为前提

  • 自定义事件是处理视图于控制器之间通信的最完美方式

作者:John Krull

John is a Software Engineer at eMortgage Logic. He has experience in web app development, agile software dev, and UI/UX design. He sp*ecializes in Ext JS, JavaScript, PHP, Perl, MySQL, HTML, and CSS.

【翻译】在Ext JS应用程序中构建可维护的控制器相关推荐

  1. 【翻译】Ext JS 6早期访问版本发布

    早期访问版本是什么 如何参与 都包括什么 Sencha Ext JS 6 Sencha Pivot Grid Sencha Cmd 6 JetBrains IDE插件 反馈 原文:Announcing ...

  2. 【翻译】Ext JS 4.2介绍

    原文:Introducing Ext JS 4.2 Ext JS 4.2包含了许多令人兴奋的增强功能和特性.你可能已经在之前的文章中阅读过相关的一些功能和特性了,如Grid组件改进.在这篇文章中,将介 ...

  3. node.js ejs_如何在Node.js应用程序中使用EJS模板

    node.js ejs by Jennifer Bland 詹妮弗·布兰德(Jennifer Bland) 如何在Node.js应用程序中使用EJS模板 (How to use EJS Templat ...

  4. rethinkdb_如何在Node.js应用程序中使用RethinkDB

    rethinkdb 这篇文章是由同行评审Agbonghama柯林斯和马丁·马丁内斯 . 感谢所有SitePoint的同行评审员使SitePoint内容达到最佳状态! Web应用程序最常见的任务之一就是 ...

  5. 【翻译】Ext JS 6.6.0的新东西

    原文:<What's New in Ext JS 6.6.0> 简介 Sencha Ext JS 6.6已经支持NPM包和开放工具.Ext JS 6.6现在可以通过NPM包让开发人员使用已 ...

  6. 【翻译】Ext JS 6 Beta发布

    原文:Ext JS 6 Beta is Now Available 概述 Ext JS 6的好处 新的Ext JS功能和工具 需要你的反馈意见 概述 很高兴,Ext JS 6 beta版本现在发布了. ...

  7. 【翻译】Ext JS最新技巧——2015-8-11

    原文:Top Support Tips Seth Lemmons:使用棒极了的Awesome Font Ext JS 6附带了一个新的海卫一主题,可以使用Font Awesome字体作为背景图像的图标 ...

  8. ext get id js_【翻译】Ext JS最新技巧——2015-8-11

    Seth Lemmons:使用棒极了的Awesome Font Ext JS 6附带了一个新的海卫一主题,可以使用Font Awesome字体作为背景图像的图标.不过,你知道如何通过"ico ...

  9. 【翻译】Ext JS——高效的编码风格指南

    原文:ExtJS - Efficient coding style guide 作者:Raja 切勿使用"new"关键字:在Ext JS中,使用"new"关键字 ...

最新文章

  1. WinAPI: 钩子回调函数之 SysMsgFilterProc
  2. API接口自动化之2 处理http请求的返回体,对返回体做校验
  3. Vmware下Centos7安装预览
  4. Python + OpenCV 太好玩了,可惜你可能还不会
  5. 接口测试用例模板_ITest:京东数科接口自动化测试实践
  6. 后端学习 - Spring5
  7. 二:熟悉 TCP/IP 协议
  8. 一些关于图论和二叉树的
  9. java项目引入json配置,TS-28 配置tsconfig.json(3):工程引用
  10. 大数据与大量数据处理_我们如何处理和使用如此大量的数据?
  11. selenium+java:获取列表中的值
  12. Eclipse配置中文(汉化)
  13. java多线程(2)----继承的方式创建多线程
  14. HTML+CSS+JAVASCRIPT 高仿低配网页版网易云音乐播放器
  15. win7笔记本电脑设置WiFi热点
  16. 粒子特效 代码(龙卷风)
  17. 私有云的优缺点_私有云的优缺点是什么?与公有云的区别
  18. mysql 报错Incorrect string value: '\xF0\x9F\x98\x84' 解决方案
  19. 防止刷新或后退页面重复提交表单
  20. windows xp系统本地磁盘图标发生变化——5种解决方法

热门文章

  1. PHP SESSION生存时间设置
  2. ssh远程连接不上服务的处理过程总结
  3. SpringBoot 精通系列-创建SpringBoot的入门项目
  4. Git使用手册:HTTPS和SSH方式的区别和使用
  5. 国外的老师是怎么教Golang的?
  6. 在Golang中使用Protobuf
  7. java后端跨域问题常用解决方案
  8. java使用netty
  9. Exchange Server导出共存环境下的邮箱列表
  10. 初学Python——字符串相关操作