原文地址:http://docs.sencha.com/extjs/4.0.7/#!/guide/mvc_pt2

【翻译 by 明明如月 QQ 605283073 本章节配套项目代码将在第3节给出】

上一节:Ext JS 4 架构你的应用 第1节 (官方文档翻译)

下一节:Ext JS4 架构你的应用 第3节 (官方文档翻译)
在上一篇文章中我们介绍了,怎样基于Ext JS构建一个 潘多拉风格的应用。
让我们探讨一下Model-View-Controller(模型-视图-控制器)架构以及怎样将其应用到相对复杂一点的
含有多个视图和模型的UI应用中。

定义你的应用

在Ext JS 3中 Ext.onReady是应用的入口,开发者也不得不自己设计一个应用架构。

 在 Ext JS 4 中我们介绍了一种类似MVC模式的架构。这个模式将帮助我们创建应用的最佳实践。
通过新的MVC包编写应用的切入点使用的是 Ext.application方法。该方法将为你创建一个Ext.app.Application 实例。
页面加载完成以后将会触发此启动方法。
应该用此方法来代替以前的 Ext.onReady ,在此方法中添加自动创建一个viewport和设置命名空间(namespace).

app/Application.js

Ext.application({name: 'Panda',autoCreateViewport: true,launch: function() {// This is fired as soon as the page is ready}
});

name  配置对应的是命名空间。

应用中所有的视图、模型、存储、控制器等都将在此命名空间内。
通过将autoCreateViewport 设置为true,按照约定,框架将会将app/view/Viewport.js文件包含进来
一个类名为 Panda.view.Viewport的类应该在此文件中定义。

Viewport 类

当我们思路我们这个UI需要哪些视图的时候,我们关注的是每个部分。Viewport 所扮演的是应用中各个视图部分的粘合剂。

它加载应用布局所需的各种视图。我们发现渐进式地来定义你的视图并且将其加入viewport中是构建你UI的最快方式。

创建一个构建块

通过利用前面文章介绍的内容,我们可以一次定义出多个视图。

app/view/NewStation.js

Ext.define('Panda.view.NewStation', {extend: 'Ext.form.field.ComboBox',alias: 'widget.newstation',store: 'SearchResults',... more configuration ...
});

app/view/SongControls.js

Ext.define('Panda.view.SongControls', {extend: 'Ext.Container',alias: 'widget.songcontrols',... more configuration ...
});

app/view/StationsList

Ext.define('Panda.view.StationsList', {extend: 'Ext.grid.Panel',alias: 'widget.stationslist',store: 'Stations',... more configuration ...
});

app/view/RecentlyPlayedScroller.js

Ext.define('Panda.view.RecentlyPlayedScroller', {extend: 'Ext.view.View',alias: 'widget.recentlyplayedscroller',itemTpl: '<div></div>',store: 'RecentSongs',... more configuration ...
});

app/view/SongInfo.js

Ext.define('Panda.view.SongInfo', {extend: 'Ext.panel.Panel',alias: 'widget.songinfo',tpl: '<h1>About </h1><p></p>',... more configuration ...
});

这里我们忽略了组件的一些配置,因为这些配置和本文核心内容无关。

在上面的配置中,你可能会注意到我们配置了3个存储。

models 和 stores

通常来说在服务端我们可以使用静态json文件里的模拟的数据。

以后我们可以参考静态json文件的内容去实现服务端的动态数据处理。
对于我们的应用,我们决定使用两个模型Station和Song.我们也需要为这两个模型创建3个存储来绑定到数据组件上。
每个存储都将从服务端来获取数据。模拟的数据文件类似下面的内容。

静态数据

data/songs.json

{'success': true,'results': [{'name': 'Blues At Sunrise (Live)','artist': 'Stevie Ray Vaughan','album': 'Blues At Sunrise','description': 'Description for Stevie','played_date': '1','station': 1},...]
}

data/stations.json

{'success': true,'results': [{'id': 1, 'played_date': 4, 'name': 'Led Zeppelin'},{'id': 2, 'played_date': 3, 'name': 'The Rolling Stones'},{'id': 3, 'played_date': 2, 'name': 'Daft Punk'}]
}

data/searchresults.json

{'success': true,'results': [{'id': 1, 'name': 'Led Zeppelin'},{'id': 2, 'name': 'The Rolling Stones'},{'id': 3, 'name': 'Daft Punk'},{'id': 4, 'name': 'John Mayer'},{'id': 5, 'name': 'Pete Philly & Perquisite'},{'id': 6, 'name': 'Black Star'},{'id': 7, 'name': 'Macy Gray'}]
}

Models(模型)

在Ext JS4 中的模型和 Ext JS 3中的Records (记录)非常像。
一个关键不同点是在模型中你可以定制一个代理、校验和关联。
在Ext JS4中Song 模型类似如下内容:

app/model/Song.js

Ext.define('Panda.model.Song', {extend: 'Ext.data.Model',fields: ['id', 'name', 'artist', 'album', 'played_date', 'station'],proxy: {type: 'ajax',url: 'data/recentsongs.json',reader: {type: 'json',root: 'results'}}
});
你可以看到我们为模型定义了一个代理(proxy )。
这一般说来是一个比较好的时间,它允许你在不需要存储(store)的条情况下获取和保存模型实例。
我们接着定义Station  类。

app/model/Station.js

Ext.define('Panda.model.Station', {extend: 'Ext.data.Model',fields: ['id', 'name', 'played_date'],proxy: {type: 'ajax',url: 'data/stations.json',reader: {type: 'json',root: 'results'}}
});

Stores(存储)

Ext JS 4中,多个存储可以使用同一个数据模型,甚至存储还可以从不同的资源来加载数据。

在我们的例子中Station 模型将被 SearchResults 和 Stations存储使用,分别从不同的地方加载数据。
一个是返回搜索结果,一个是返回用户喜爱的站点的数据。为了达到这个目的,我们的存储需要重写模型中定义的Proxy。

app/store/SearchResults.js

Ext.define('Panda.store.SearchResults', {extend: 'Ext.data.Store',requires: 'Panda.model.Station',model: 'Panda.model.Station',// Overriding the model's default proxyproxy: {type: 'ajax',url: 'data/searchresults.json',reader: {type: 'json',root: 'results'}}
});

app/store/Stations.js

Ext.define('Panda.store.Stations', {extend: 'Ext.data.Store',requires: 'Panda.model.Station',model: 'Panda.model.Station'
});

app/store/RecentSongs.js

Ext.define('Panda.store.RecentSongs', {extend: 'Ext.data.Store',model: 'Panda.model.Song',// Make sure to require your model if you are// not using Ext JS 4.0.5requires: 'Panda.model.Song'
});

当前的 Ext JS版本,在一个存储中的模型属性不会自动创建一个依赖。这就是为什么我们不得不指定requires 来动态加载模型的原因。

同样地,根据惯例,我们经常将store的名字写成复数的形式,而把模型名写成单数形式。

为我们的应用添加 stores (存储)和models(模型)

app/Application.js

Ext.application({...models: ['Station', 'Song'],stores: ['Stations', 'RecentSongs', 'SearchResults']...
})

Ext JS 4 MVC 包的另外一个优势是应用将自动加载在application中配置的模型和存储。

应用粘合剂(viewport)

目前为止views, models 和stores都有了,我们需要将其粘合在一起。我们将一个个视图添加到viewport中。

这对于调试任何一个错误的视图配置非常容易。
Ext.define('Panda.view.Viewport', {extend: 'Ext.container.Viewport',

Viewport 类通常拓展自 Ext.container.Viewport 这就使得你的应用可以占据浏览器窗口的所有可用空间。

   requires: ['Panda.view.NewStation','Panda.view.SongControls','Panda.view.StationsList','Panda.view.RecentlyPlayedScroller','Panda.view.SongInfo'],

我们也设置了viewport的视图依赖。这里允许我们使用之前在视图中定义好的别名作为xtype的值。

   layout: 'fit',initComponent: function() {this.items = {xtype: 'panel',dockedItems: [{dock: 'top',xtype: 'toolbar',height: 80,items: [{xtype: 'newstation',width: 150}, {xtype: 'songcontrols',height: 70,flex: 1}, {xtype: 'component',html: 'Panda<br>Internet Radio'}]}],layout: {type: 'hbox',align: 'stretch'},items: [{width: 250,xtype: 'panel',layout: {type: 'vbox',align: 'stretch'},items: [{xtype: 'stationslist',flex: 1}, {html: 'Ad',height: 250,xtype: 'panel'}]}, {xtype: 'container',flex: 1,layout: {type: 'vbox',align: 'stretch'},items: [{xtype: 'recentlyplayedscroller',height: 250}, {xtype: 'songinfo',flex: 1}]}]};this.callParent();}
});

由于 Viewport拓展自Container,Container(容器)还不能有停驻元素,我们添加一个面板作为viewport的唯一元素。

由于viewport中laylout(布局)设置为fit,这个面板将和viewport的尺寸相同。
我们在视图中没有定义flex, width, height等属性。因此我们可以非常容易的在一个地方就可以调整应用的整体布局,增加了架构的可维护性和灵活性。

应用逻辑

在Ext JS 3中,我们通常将应用的逻辑添加在视图的按钮处理器方法中,绑定子组件和拓展视图时重写拓展视图的方法。

然而正如你不应该在HTML里面写内联的CSS一样,我们也应该将视图和应用的逻辑分开。
 Ext JS 4中我们在MVC包里提供了controlleres(控制器) 类。
他们负责监听来之视图或者其他控制器的事件,并且实现对应事件的逻辑。这样的设计将带来很多好处。
一个好处是,你的应用逻辑不绑定视图实例。
另外在Ext JS 3中,你有也许要嵌套多个视图,每个视图都添加应用逻辑。通过将应用逻辑移到控制器,变得更加集中,使得应用的维护和修改变得更加容易。

创建 Controllers(控制器)

app/controller/Station.js

Ext.define('Panda.controller.Station', {extend: 'Ext.app.Controller',init: function() {...},...
});

app/controller/Song.js

Ext.define('Panda.controller.Song', {extend: 'Ext.app.Controller',init: function() {...},...
});

当你的应用中包含了这些控制器,框架将自动加载这个控制器并且调用功能init方法。

在init方法中,你应该设置对视图和应用事件的监听器。
在大型的应用中,你也许希望在运行时再加载额外的控制器。你可以通过getController 方法来实现。
someAction: function() {var controller = this.getController('AnotherController');// Remember to call the init method manuallycontroller.init();
}

当你在运行时想加载外部控制器,你一定要记住手动去调用init方法。

对我们的例子来说,如果我们想让框架加载和初始化我们的控制器,我们需要将其添加到application 的控制器数组中。

app/Application.js

Ext.application({...controllers: ['Station', 'Song']
});

设置监听器

...
init: function() {this.control({'stationslist': {selectionchange: this.onStationSelect},'newstation': {select: this.onNewStationSelect}});
}
...

control方法传递一个组件必须的对象。在我们例子里,组件只需要简单的使用视图的xtype属性。

每个查询都绑定一个监听器配置。 在每个监听器配置里,我们想要监听事件名。
如果想要了解有哪些可用的事件可以查询API 文档搜索events(事件)部分。
监听器配置的值是一个当事件发生时执行的方法。这个方法的范围一般是控制器自身。

app/controller/Song.js

...
init: function() {this.control({'recentlyplayedscroller': {selectionchange: this.onSongSelect}});this.application.on({stationstart: this.onStationStart,scope: this});
}
...

除了RecentlyPlayedScroller视图中监听selectionchange 事件,我们也为应用事件设置了一个监听器。

我们通过application实例的on方法来实现。
每个控制器使用 this.application来访问application 实例。

Application 事件对于事件和多个控制器对应的情况下非常有用。
不是在每个控制器中都监听同一个视图事件,只有一个控制器监听此视图事件和出发一个应用范围的事件,其他控制器来监听。
这也允许控制器在不知道或者不相互依赖的情况下彼此交互。
我们的Song 控制器对新创建站点比较敏感,因为当创建新的站点时它需要更新song滚动条和歌曲信息。
我们看一下Station 控制器:

app/controller/Station.js

..
onStationSelect: function(selModel, selection) {this.application.fireEvent('stationstart', selection[0]);
}
...

我们只是简单地获取selectionchange 事件提供的单个选择项然后将其作为触发stationstart 事件的一个参数。

结论

在本文中,我们了解了应用的基本架构。下一节我们将了解更高级的控制器技术,通过实现我们的控制器行为和为视图添加更多的细节继续拓展我们的潘多拉应用。

Ext JS 4 架构你的应用 第2节 (官方文档翻译)相关推荐

  1. Sencha Cmd创建Ext JS示例项目

    Sencha提供了免费的Cmd工具,可以用来创建Ext JS项目并提供了一些便利的功能. Sencha也在官方文档中提供了一个示例来演示如何创建一个Sample Login App. 本文就介绍一下这 ...

  2. 第2章[2.3] 基于Ext JS的MVC/MVVM架构的应用开发模式

    Ext JS 对MVC 和MVVM两种架构都支持.这两种架构都是根据逻辑划分程序的代码,两种各有优劣. MVC是什么? Model, View , Control的首字母. 在MVC架构中,大多数类都 ...

  3. Ext JS 6.7 中文文档:应用架构介绍(MVC/MVVM)

    最近为了做内网的后台学了下 Ext JS,觉得挺有意思的,顺手翻译一下文档,主要是架构部分和核心概念部分. 这个文档是我目前看到的最好的关于 MVC.MVVM 的解释与探讨,十分值得参考. 本篇目录 ...

  4. 《深入浅出Ext JS》(第2版)即将上市

    <深入浅出Ext JS>(第2版)将于5月初上市.在此非常感谢各位购买和阅读本书第1版的广大读者,感谢大家对本书的关注,及阅读后给予本书的中肯评论.同时感谢,本书改版之前,积极参与图灵组织 ...

  5. Ext JS图书风暴来袭!

    2009年最值得期待的Ajax图书 --<深入浅出Ext JS> 一.本书赞誉 涵盖Ext JS 3.0新特性 Ext JS专家力作,实例丰富,完美结合理论和实践 Ajax中国.Dojo中 ...

  6. 小弟的新书《Ext JS权威指南》终于出版了

    链接:http://product.china-pub.com/3661375&weibo#ml <ext js权威指南> 前 言 第1章 ext js 4开发入门 / 1 1.1 ...

  7. Ext JS 4 Beta 3 今天可以下载了

    今天,我们很高兴能在每周发布周期的日子里发布ExtJS 4 Beta 3,离我们的目标,ExtJS 4.0最终发布版越来越近了.到目前为止,在你们的帮助下,我们做了大约一千个改进.错误修复和新功能.自 ...

  8. Ext JS 6开发实例(一)

    很久没写文章了,主要原因和大家差不多,都要为生活奔忙,搞了两个小项目.这两个小项目很凑巧,都可以使用Ext JS来开发,这正是练习使用Ext JS 6的好机会,自然不会错过. 很多读者可能会问,为什么 ...

  9. 【翻译】针对多种设备定制Ext JS 5应用程序

    原文:Tailoring Your Ext JS 5 Application for a Multi-Device World 概述 鉴于当今设备和表单因素的扩散,要针对所有这些可能性来优化应用程序已 ...

  10. 介绍Ext JS 4.2的新特性的《深入浅出Ext JS》上市

    以用户为中心的时代,应用的界面外观变得越来越重要.然而,很多程序员都缺乏美术功底,要开发出界面美观的应用实属不易.Ext JS的出现,为广大程序员解决了这一难题.它有丰富多彩的界面和强大的功能,是开发 ...

最新文章

  1. 解决MyEclipse2015启动时:Java was started but returned exit code=1问题
  2. 用命令行在控制台里玩斗地主,试过没?
  3. makefile跨平台,动态库,静态库
  4. ZeroMQ接口函数之 :zmq_msg_init - 初始化一个空的ZMQ消息结构
  5. 嵌入式C语言之位运算 ..|.~.
  6. spring mvc hello
  7. Java如何以及为什么使用Unsafe?
  8. c语言数组最大可定义多少位_C语言求数组的最大值三种方法
  9. PHP的ISAPI和FastCGI比较
  10. Redis高可用方案哨兵机制------ 配置文件sentinel.conf详解
  11. jQuery初识 - jQuery案例练习
  12. 【Oracle】权限
  13. 无法安装 DotNetCore.1.0.0-VS2015Tools.Preview2解决方法
  14. js margin作用到父元素_子元素的 margin-top 传递给了父元素
  15. 电子电路学习笔记(12)——稳压二极管
  16. 车辆维修管理系统mysql_数据库课设计 汽车修理管理系统.doc
  17. Java项目:springboot宠物医院管理系统
  18. MybatisPlus多表关联查询
  19. 专利检索常用的十八个网站
  20. 微信转账2020假图片_2020精致简约背景图片 | 简约唯美的微信朋友圈背景图

热门文章

  1. java牛顿法求方程根_牛顿迭代法 求方程根
  2. Oracle字符集及其查看和修改
  3. Vue一级二级三级域名下cookie值共享(不同域名cookie共享)
  4. js 实现井字棋游戏
  5. 科学计算机使用方法,[转载]科学计算器的使用方法
  6. python爬取某人所有微博_python爬取微博用户关注和粉丝的公开基本信息
  7. 3分钟在线开通优惠费率的微信支付商户号(商户收款码)
  8. openwrt配置内核,加载air720 4G模块的USB串口设备
  9. STM32F103单片机使用ULN2003驱动步进电机
  10. Ubuntu16.04编译Android源码系列一——7.1.2和4.4及踩坑