🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
本文地址:[http://blog.csdn.net/sushengmiyan/article/details/38537431](http://blog.csdn.net/sushengmiyan/article/details/38537431) 本文作者:[sushengmiyan](http://blog.csdn.net/sushengmiyan) -------------------------------------------------------------资源链接----------------------------------------------------------------------- 翻译来源:[http://docs.sencha.com/extjs/5.0.0/application_architecture/application_architecture.html](http://docs.sencha.com/extjs/5.0.0/application_architecture/application_architecture.html)[](http://docs.sencha.com/extjs/5.0.0/apidocs/#!/api/Ext.toolbar.Toolbar) 本文仅仅是将英文翻译为了中文,方便大家更是方便自己后续阅读,仅此而已。 ------------------------------------------------------------------------------------------------------------------------------------------------ Ext JS提供了mvc和mvvm的应用程序框架支持,这两种架构方法都是关注于将应用程序代码和业务逻辑分离。每一种方法都有自己的优点,这取决于怎么分离应用程序模块。 这篇指导的目的就是提供有关组成这些框架的组件的基础知识。 ### ### 什么是MVC框架?What is MVC?  在一个MVC框架中,大多数的类要么是模型(model)要么是视图(view)要么是控制器(controller)。用户(user)与视图(view)交互,视图(view)呢又显示模型(model)中的数据(data)。这些交互都被控制器(controller)监控,控制器(controller)又在需要的时候通过更新模型(model)和视图(view)与响应交互。 通常情况下,模型(model)和视图(view)都不了解彼此,因为控制器(Controller)对直接更新负主要责任。一般来讲,在一个应用程序中控制器(controllers)包含了大多数的应用逻辑。在理想情况下视图(views)会包含一点点业务逻辑。模型(models)主要是一个用户数据接口,包含着管理变化数据的业务逻辑。 MVC的目标是清晰的划分哥哥应用程序中类的责任。因为每一个类都有明确的责任,在大型的环境中,它们就暗暗解耦了。这就让应用程序容易测试盒维护,代码复用性也加强了。 ### ### 什么是mvvm框架?what is mvvm ? mvc和mvvvm的最大的区别就是MVVM有一种叫做视图模型(viewmodel)的抽象视图。视图模型利用一种叫作数据绑定(data binding)的技术将模型的数据和视图的展示之间的变化进行调和。 结果是,模型和框架完成尽可能多的工作,最大限度地减少或消除应用程序逻辑,直接操作视图。 ### 返回用户(returning users) Ext js 5引入了支持MVVM的架构支持,同时是对mvc中的改进。我们鼓励你去探索和研究这些改进,需要值得注意的是,我们为ext js 4的mvc的继续支持做了很大的努力。 ### mvc 和mvvm 为了理解如何在你的应用程序之间选择合适的框架,我们应该从定义的这些不同表现开始: (M:Model)模型:这是为您的应用程序的数据。一组类(称为“模型”)定义了字段的数据(如用户模型的用户名和密码字段)。通过数据包模型知道如何展示自己,可以通过关系与其他模型关联。模型通常用于给存储提供数据的表格和其他组件。模型也是一个理想的选中为任何你可能需要的数据逻辑,比如验证、转换等。 (V:View)视图:一个视图是任何类型的组件,是视觉表示。例如,网格,树和面板都是考虑的观点。 (C:Controller):控制器:控制器是用来使你的应用程序工作的视图逻辑的管理职责位置,这可能需要渲染视图、路由实例化模型,和任何其他类型的应用程序逻辑。 (vm: viewmodel):视图模型是一个管理制定视图的数据管理器。它允许感兴趣的组件绑定和数据更改通知。 这些应用程序架构提供结构和框架代码的一致性。按照惯例我们建议将提供许多重要的好处:     每个应用程序在相同的方式工作,所以你只需要学一次。     很容易在应用程序之间共享代码。     您可以使用Sencha Cmd创建优化的生产版本的应用程序。 ### 构造一个简单的APP 在我们开始之前,让我们通过Sencha Cmd构建一个示例应用程序。从命令行发出以下命令: ~~~ sencha generate app -ext MyApp ./app cd app sencha app watch ~~~ 注意:如果你不熟悉这些命令,建议你从熟悉sencha cmd开始:[点击这里学习](http://blog.csdn.net/sushengmiyan/article/details/38313537) ### 应用程序预览 在我们讲解关于组织MVC MVVM 、MVC+MV的部分知识时,让我们看一下sencha cmd生成的应用程序的结构: ### 文件目录结构 Ext js应用程序统一为每一个app提供了统一相同的目录结构。我们推荐的是,所有的类都放在app文件夹下,这个文件夹包含子文件夹,里面防止你的Models 和stores还有view元素。视图元素包括View、viewcontrollers和viewModels应该放置在一个文件夹下,这样方便管理,可以参考下面的view下的main文件夹。 ![](https://box.kancloud.cn/2016-02-03_56b214e8e955e.jpg) ### 命名空间(namespace) 每一个类的第一行代码是各种地址,地址(adress)叫做命名空间,命名空间的格式如下: ~~~ <AppName>.<foldername>.<ClassAndFileName> ~~~ 在我们的示例程序中,‘MyApp’就是应用程序的名称,view是文件夹名称,main是子文件夹,Main是类并且也是一个js文件。通过以上信息,我们可以在如下目录找到Main.js这个文件: ~~~ app/view/main/Main.js ~~~ 如果这个文件找不到,Extjs会给我们抛出一个异常信息,直到你解决这个问题。 ### 应用程序(application) 让我们从index.html开始看 ~~~ <!DOCTYPE HTML> <html> <head> <meta charset="UTF-8"> <title>MyApp</title> <!-- The line below must be kept intact for Sencha Cmd to build your application --> <script id="microloader" type="text/javascript" src="bootstrap.js"></script> </head> <body></body> </html> ~~~ Ext js使用Microloader去加载应用程序资源,这些资源基于app.json文件描述。这就省去了我们在index.html中引入其他信息的麻烦事。有了app.json,应用程序需要的meta-data都会在一个单独的文件位置存储,sencha cmd就会有效的构造你的应用程序。 ### app.js 当我们生成的应用程序之前,我们创建了一个类(Application.js)和推出了它的一个实例(在app.js)。你可以看到app.js的内容如下: ~~~ /* * This file is generated and updated by Sencha Cmd. You can edit this file as * needed for your application, but these edits will have to be merged by * Sencha Cmd when upgrading. */ Ext.application({ name: 'MyApp', extend: 'MyApp.Application', autoCreateViewport: 'MyApp.view.main.Main' //------------------------------------------------------------------------- // Most customizations should be made to MyApp.Application. If you need to // customize this file, doing so below this section reduces the likelihood // of merge conflicts when upgrading to new versions of Sencha Cmd. //------------------------------------------------------------------------- }); ~~~ autoCreateViewport是 Ext JS 5的一个新特性。通过指定autoCreateViewport容器类,您可以使用任何类作为你的视窗。在上面的例子中,我们已经确定MyApp.view.main。主要(一个容器类)是我们的视窗。 autoCreateViewport配置指示应用程序来创建指定的视图和附加窗口插件。这个连接视图和文档的主体。 ### application.js 每一个Ext JS应用程序启动应用程序类的一个实例。这个类的目的是由app.js launch-able以及instantiable进行测试。 下面这个application.js是有sencha cmd自动生成的: ~~~ Ext.define('MyApp.Application', { extend: 'Ext.app.Application', name: 'MyApp', stores: [ // TODO: add global/shared stores here ], launch: function () { // TODO - Launch the application } }); ~~~ apllicatin类包含了你需要的全局变量像应用程序的命名空间,共享的stores等。 ### 视图(Views) 视图只不过是一个组件,它是Ext.Component的一个子类。一个视图包含所有应用程序的视觉方面。 如果你打开应用程序的在“main”文件夹下的Main.js,您应该看到下面的代码。 ~~~ Ext.define('MyApp.view.main.Main', { extend: 'Ext.container.Container', xtype: 'app-main', controller: 'main', viewModel: { type: 'main' }, layout: { type: 'border' }, items: [{ xtype: 'panel', bind: { title: '{name}' }, region: 'west', html: '<ul>...</ul>', width: 250, split: true, tbar: [{ text: 'Button', handler: 'onClickButton' }] },{ region: 'center', xtype: 'tabpanel', items:[{ title: 'Tab 1', html: '<h2>Content ...</h2>' }] }] }); ~~~ 请注意,视图不包含任何应用程序逻辑。你所有的视图的逻辑应该被包括在它们,这在下一节中我们将讨论。 这个特定的视图定义了一个容器边界与西方和中心地区的布局。这些地区包括一个面板工具栏包含一个按钮和一个标签面板只有一个选项卡。如果您不熟悉这些概念,看看我们的入门指南。 请看两个有趣的这个视图控制器和视图模型配置。 ### 控制器配置(Controller config) 控制器配置允许您为视图指定ViewController。当以这种方式在ViewController上指定一个视图,它就变成了一个事件处理程序和引用容器。这给了它们一个一对一的关系从视图组件和事件。在下一节中我们将进一步讨论控制器。 ### 视图模型配置(viewmodel config) viewModel配置视图允许您指定一个视图模型。ViewModel是该组件和它的子视图的数据提供者。通常使用视图模型中包含的数据绑定配置添加到组件想要展示或编辑这些数据。 在上面的视图中,您可以看到,左边的面板的标题是绑定到视图模型。这意味着标题将被填充数据的“名称”值,由ViewModel管理。如果ViewModel的数据变化,标题的值将自动更新。我们将在本文的后面讨论视图模型。 ### 控制器(controllers) 接下来,让我们看看控制器。自动生成的application.js看起来像这样: ~~~ Ext.define('MyApp.view.main.MainController', { extend: 'Ext.app.ViewController', requires: [ 'Ext.MessageBox' ], alias: 'controller.main', onClickButton: function () { Ext.Msg.confirm('Confirm', 'Are you sure?', 'onConfirm', this); }, onConfirm: function (choice) { if (choice === 'yes') { // } } }); ~~~ 如果你回顾你的视图,Main.js,您会注意到一个函数指定tbar按钮的处理程序。处理程序映射到一个功能叫做onClickButton控制器。正如您可以看到的,该控制器已准备好应对该事件没有通过特殊设置。 这使为您的应用程序添加逻辑非常容易。所有你需要做的就是onClickButton函数自定义的视图控制器有一个一对一的关系。 单击视图的按钮时,将创建一个消息框。这个消息框包含它自己的函数调用onConfirm,作用域相同的控制器。 viewcontroller旨在: 使连接视图使用“liseners”和“reference”配置明显。 利用视图来自动管理的生命周期相关的ViewController。从实例化到销毁Ext.app.ViewController与引用它的组件。第二个实例相同的视图类  ViewController会得到自己的实例。当这些观点被销毁,他们的相关ViewController实例将被摧毁。 为使嵌套视图直观提供封装。 ### 视图模型viewmodels 下一步,我们将看Viewmodel的代码,如果你打开MainModel.js文件,你会看到下面的代码: ~~~ Ext.define('MyApp.view.main.MainModel', { extend: 'Ext.app.ViewModel', alias: 'viewmodel.main', data: { name: 'MyApp' } //TODO - add data, formulas and/or methods to support your view }); ~~~ 一个视图模型是一个类,管理一个数据对象。然后这类允许感兴趣数据视图绑定到它和更改的通知。ViewModel ViewController一样,属于引用它。因为视图模型与一个视图相关联,他们也可以链接到一个父视图模型由祖先组件的组件层次结构。这允许子视图只是“继承”的数据父视图模型。 从我们的观点我们创建了一个链接到ViewModel Main.js ViewModel配置。该链接允许绑定配置的setter从viewModel到自动设置数据视图以声明的方式。在MainModel.js是数据内联的例子。也就是说,您的数据可以是任何东西,来自任何地方。数据可能会提供的任何形式的代理(AJAX、Rest等)。 ### 模型和存储(models and stores) 模型和存储组成应用程序信息门户。大部分通过这两个类进行数据发送、检索、组织、和“建模”。 ### 模型(models) Ext.data模型表示在应用程序中任何类型的可持续数据。每个模型都有字段和函数,允许您的应用程序“模型”数据。模型是最常用的结合。store可以使用数据绑定组件,如网格树,和图表。 我们的样例应用程序目前并不包含一个模型让我们添加以下代码: ~~~ Ext.define('MyApp.model.User', { extend: 'Ext.data.Model', fields: [ {name: 'name', type: 'string'}, {name: 'age', type: 'int'} ] }); ~~~ 如前所属,你应该先需要创建一个User.js文件,然后放置在model文件夹下。 ### 字段(fields) Ext.data.Model描述的记录包含值或属性称为“字段”。模型类可以声明这些字段使用“字段”配置。在这种情况下,“名字”宣称是一个字符串,年龄是一个整数。还有其他字段类型可参考可用的API文档。 尽管有很好的理由声明字段及其类型,这样做不是必需的。如果你不包括字段配置,数据会自动读取和插入到数据对象。如果您想要定义字段数据需求: 验证 默认值 功能转换 让我们设置一个store让这俩配合工作。 ### stores store是一个客户端缓存的记录(一个模型类的实例).store提供排序功能,过滤和查询中包含的记录。 这个示例应用程序不包含一个store,但是不用担心。简单地定义您的存储和分配模型 ~~~ Ext.define('MyApp.store.User', { extend: 'Ext.data.Store', model: 'MyApp.model.User', data : [ {firstName: 'Seth', age: '34'}, {firstName: 'Scott', age: '72'}, {firstName: 'Gary', age: '19'}, {firstName: 'Capybara', age: '208'} ] }); ~~~ 将User.js增加到 app/store目录下。 你在Apllication.js 中增加配置,如下: ~~~ stores: [ 'User' ], ~~~ 在本例中,存储直接包含数据。大多数现实世界的情况下会要求你使用代理收集数据模型或商店。代理允许数据提供商和应用程序之间的数据传输。 你可以阅读更多关于模型、存储和数据提供者在我们的数据指南。