这篇翻译不完整。请帮忙从英语翻译这篇文章

这篇文章提供了一个对模型-视图-控制器 (MVC) 软件架构模式背后的原理的基础介绍,然后将解释这些原理是如何被一种流行的应用开发框架Ember.js实现的。

模型-视图-控制器 背后的理论

模型-视图-控制器(MVC)是一种软件架构模式,通常被用于实现用户接口:因此它是一种架构web应用流行的选择。通常来说,它将应用程序的逻辑分成三个独立的部分,提高模块性、易用度和重用性。它同样使应用程序更加的灵活,易于迭代。

为了使意思更加清楚,让我们想象一个简单的购物列表app。所有我们想要的是一个包含我们这周要买的每个物品的名称、数量和价格的清单。下面我们将描述如何使用MVC实现一些功能。

Diagram to show the different parts of the mvc architecture.

模型

模型定义了app应该包含的数据。如果数据的状态发生改变,接下来模型通常会通知视图(因此显示可以根据需要改变),有时也会通知控制器(如果更新视图需要不同的逻辑)。

回到我们的购物清单app,模型将指定清单包含什么数据——物品、价格等等。——已及哪些物品已经存在。

视图

视图定义了app的数据应该怎样显示。

在我们的购物清单app中,视图将会定义清单如何呈现给用户,以及如何接受来自模型的显示数据。

控制器

控制器包含了更新模型和/或视图的逻辑,来响应于来自app用户的输入。

例如,我们的购物清单可以有输入表单和添加物品、删除物品的按钮。这些操作要求模型被更新,因此输入被发送到控制器,然后控制器适当地操作模型,然后控制器将更新的数据发送到视图。

然而,您可能还希望只更新视图使数据以不同格式显示,例如,将物品顺序更改为字母顺序,或将最低价格更改为最高价格。在这个例子中,控制器能直接处理此操作,无需更新模型。

MVC在Web上的演化

作为一名Web开发者,这个模式可能是非常熟悉的,即使您以前没有有意识地使用它。您的数据模型可能包含在某种数据库中(它可能是一个像MySQL这样的传统服务器端数据库,或着一个服务器端的解决方案,就像IndexedDB [en-US]。)您app的控制代码可能是用HTML/JavaScript写的,您的用户界面可能是用HTML/CSS/其它您喜欢的语言。这听起来非常像MVC,但MVC使这些组件遵循一种更严格的模式。

在Web初期,MVC架构主要实现在服务器端,客户端通过表单或链接请求更新,和接收更新过的视图以显示在浏览器中。然而,近年来,随着客户端数据存储的出现,更多的逻辑被推给客户端,并且XMLHttpRequest允许根据需要进行部分页面更新。

流行的Web框架比如AngularJSEmber.jsBackbone全部实现了一个MVC架构,尽管方式略有不同。

Ember.js如何将MVC引入实践中

Ember——我们将在这个系列中使用的框架——根据一组严格的原则和规则实现了MVC;这篇文档提供了一个对您所需要了解的东西的简单总结。您可以在Ember的文档里阅读到很多关于它的信息——一个好的开始是这篇Ember.js Guides and Tutorials,以及浏览侧边栏的Getting Started小节。

最后,因为我们使用了Ember CLI将大量过程自动化,您应该将这篇文档Ember CLI documentation留在手边。

Ember的视图层

在Ember中,视图与一般MVC中的视图略有不同。在MVC术语中,我们通常认为视图是“整个UI层”,而在Ember中,视图是UI的另一个特定组件,连同routetemplate

一个典型的简单Ember.js UI使用Route对象和template文件来处理视图。Route指定您的用户将会访问哪个template文件的URL。以及同样指定了template文件将会从哪个模型展示数据。每个route被表示为JavaScript文件。Template指定UI应该是什么样子,并用 Handlebars template 文件(.hbs.)表示。这些是插入了特殊的动态表达式的HTML文件,表达式包含在双花括号中({{  ... }})。双花括号最简单的形式可以获取模型(或控制器)中包含的数据/属性,并在UI中输出它们,例如:

<div class="entry">
  <h1>{{title}}</h1>
  <div class="body">
    {{body}}
  </div>
</div>

当模型/控制器改变时,这些属性将会自动的更新在template中。

Ember CLI能够产生一个route和相关联的模板,通过使用下面的命令:

ember generate route my-route-name

这将会产生:

  1. 一个JavaScript文件,在目录your-app-root/app/routes下,用以控制route。
  2. 一个Handlebars template,在目录your-app-root/app/templates下,定义了将会出现在指定URL上的内容。
  3. 一个单元测试文件,在目录your-app-root/tests/unit/routes下,在这个文件中您可以对您的route的功能定义一个测试。

这个route文件将包含一个基本的框架,以便您开始写任何必要的route逻辑。

import Ember from 'ember';

export default Ember.Route.extend({
  // your own features, as required
});

非常像其它的MVC框架,Ember提供一个核心应用程序的基础结构,以便您能通过扩展来自定义这些结构,来满足应用程序的需求。这段代码导入主Ember对象,然后允许您通过调用其extend方法在Ember的内置Route对象之上构建功能。这是一个非常常见的模式,在构建应用程序时,您将开始认识到这一模式。

这个route和template文件都将被命名为相同的名字,比如shopping-list.jsshopping-list.hbs,所以它们默认关联在一起;然后用户可以使用视图,在your-server.com/shopping-list/ (或在无论您怎么命名.)上。

Ember控制器

Ember.js使用controller对象表示控制器,这些对象包含在JavaScript文件中。

Ember CLI能够使用下述语法产生一个控制器:

ember generate controller name-of-my-controller

这将会产生两个新文件:

  1. 一个JavaScript文件,在目录your-app-root/app/controllers下,用于控制特定的模型/视图。
  2. 一个单元测试文件,在目录your-app-root/tests/unit/controllers下,在这个文件中您可以对您的控制器的功能定义一个测试。

所以,对于我们购物清单的例子,如果我们已经有一个名为shopping-list的route和template,产生一个名为shopping-list的控制器合情合理。像这样命名它将会把这个控制器与正确的route和/或模型自动关联。

产生的控制器文件包含:

import Ember from 'ember';

export default Ember.Controller.extend({
  // your own features, as required
});

以与我们的route类似的方式,我们的控制器导入主Ember对象并扩展默认Controller对象,以允许我们创建自己的自定义控制器,它执行我们想要的任何操作。

Ember模型

Ember.js使用model对象表示模型,这些对象就像之前一样被包含在JavaScript文件中。

Ember CLI使用下述语法可以产生一个模型。

ember generate model name-of-my-model

这将会产生两个新文件:

  1. 一个JavaScript文件,在目录your-app-root/app/models下,定义了于特定视图关联的数据。
  2. 一个单元测试文件,在目录your-app-root/tests/unit/models下,在这个文件中您可以对您模型的功能定义一个测试。

所以,对于我们购物清单的例子,产生一个名为shopping-list的模型合情合理。像这样命名它将会把这个模型与正确的route和/或控制器自动关联。

产生的模型文件包含:

import DS from 'ember-data';

export default DS.Model.extend({
  // your own features, as required
});

以与我们的route和控制器类似的方式,我们的模型导入主Ember对象并扩展默认Model对象,以允许我们创建自己的自定义模型,它执行我们想要的任何操作。

下一步

现在我们已经了解了Ember和MVC背后的简单理论,接下来我们将开始付诸实践及构建一个真实基于Ember的基础MVC应用。

文档标签和贡献者

此页面的贡献者: ShuXin_Shu
最后编辑者: ShuXin_Shu,