拥抱 Ember.js 的世界
有很多可用的 JavaScript 库,其中大多数都非常擅长提供典型网站所需的传统的以 DOM 为中心的交互。但是,当需要为单页应用程序构建可管理的代码库时,就需要一整套新框架来解决问题。
老话说得好:“用最好的工具完成任务”。
并不是说像 jQuery 这样的传统库不能帮助您构建类似桌面的体验,它只是不是它的用例,并且缺少数据绑定、事件路由和状态管理等功能。当然,您可能可以拼凑一堆插件来实现其中一些功能,但在我看来,从专门从头开始构建的框架来解决这些特定问题更有意义。老话说得好:“用最好的工具完成任务。”
我最近接受了 Ember.js 团队的采访;我的动机是想要了解我所说的“新热点”:Ember.js。
Ember 符合我上面描述的要求,并且以一种让人想起 jQuery 如何让开发人员快速启动和运行的方式。该团队特意采取措施,利用多年从构建大型应用程序中获得的专业知识和知识,抽象化了设计和构建基于模型/视图/控制器的应用程序所固有的许多复杂性。
我想做的是通过一个由多部分组成的文章系列帮助您加快使用 Ember.js 的速度,该系列文章将逐步向您介绍该框架的概念。我们将从通常的介绍开始(恰好是这篇文章),然后逐渐构建一个完整的应用程序。最重要的是,这也将帮助我强化我已经学到的概念,也许还能学到一些新技术!我会尽力让 Ember.js 团队审查此材料的准确性,甚至可能为其贡献一些有价值的内容。
在我们继续之前,请注意:Ember.js 为您带来了很多魔力。有时您会看着代码并说“啊?它是怎么做到的?”我已经去过那里了,我会尽力提炼一些东西,但我不会深入研究 Ember 框架代码的内部。相反,我将讨论如何利用其工具和 API 来构建您的应用程序。
所以让我们开始吧。
核心概念
Ember.js 不是构建传统网站的框架。
首先要记住的是,Ember.js 不是用于构建传统网站的框架。像 jQuery 和 MooTools 这样的库非常适合这一点。如果您正在考虑 Ember.js,那么我们的假设是您正在寻求构建类似桌面的体验 - 尤其是可扩展的体验。事实上,该框架的口号是“一个用于开发雄心勃勃的 Web 应用程序的框架”,这告诉您它显然不是您爸爸的 JavaScript 库。
我之前提到过,Ember 利用 MVC 模式来促进正确的代码管理和组织。如果您从未进行过基于 MVC 的开发,那么您绝对应该阅读它。 Nettuts+ 有一篇关于该主题的精彩文章。对于那些熟悉这些概念的人来说,您应该有宾至如归的感觉。我一直听到的一件事是,从 Backbone 迁移到 Ember.js 实际上很容易,因为 Ember 为您做了很多繁重的工作,同时仍然保持那些开发人员习惯的代码组织模式。 p>
Ember 还依赖于客户端模板......很多。它使用 Handlebars 模板库,该库提供允许您创建基于 HTML 的动态模板的表达式。 Ember 开发人员可以将数据绑定到这些可嵌入表达式,并动态更改其应用程序的显示。例如,我可以创建一个模板,该模板可以接收一组人员并将其显示在无序列表中:
<ul> {{#each people}} <li>Hello, {{name}}!</li> {{/each}} </ul>
注意“#each”表达式用作循环指令,枚举“people”数组的每个元素并将“{{name}}”表达式替换为实际值。需要注意的是,双括号是 Handlebars 用来识别表达式的标记。这是一个小示例,稍后我们将深入了解更多细节。
Handlebars 是一个非常强大的客户端模板引擎,我建议不仅查看 Ember 指南,还查看 Handlebars 网站本身,以充分掌握可用的选项。您将会经常使用它。
设置 Ember
Ember.js 依赖于其他库,因此您需要获取 jQuery 和 Handlebars 的副本。但是,等等,我不是说过 jQuery 和 Ember 在不同的空间发挥作用吗?嗯,是的,我做到了,但事情是这样的:Ember 团队致力于不重新发明轮子。他们选择 jQuery 来做它最擅长的事情:使用 DOM。这是一件好事,因为 jQuery 在这方面确实很擅长。这也是他们选择 Handlebars 的原因,这是一个出色的模板库,恰好由 Ember 核心团队成员 Yehuda Katz 编写。
获取所需文件的最简单方法是访问 Ember.js Github 存储库并下载入门工具包。这是供您开始使用的样板。在撰写本文时,它包含:
- 人类 1.0 RC1
- 处理栏 1.0 RC3
- jQuery 1.9.1
还有一个基本的 html 模板,其编码包含所有关联的库(jQuery、Ember 等),以及 Handlebars 模板和“app.js”的示例,其中包含用于启动基本的 Ember 应用程序。
<script src="js/libs/jquery-1.9.1.js"></script> <script src="js/libs/handlebars-1.0.0-rc.3.js"></script> <script src="js/libs/ember-1.0.0-rc.1.js"></script> <script src="js/app.js"></script>
请注意,app.js 不是框架的一部分。这是一个普通的 ole JavaScript 文件;您可以将其命名为任何您想要的名称。而且,虽然我们将在本教程系列中使用它,但以后您可能最终会将 JavaScript 拆分为多个文件,就像处理任何其他网站或应用程序一样。此外,Ember 并不期望您的框架文件有特定的目录结构。
当您查看入门工具包代码时,它可能看起来像典型的网站代码。从某些方面来说,你是对的!不过,一旦我们开始组织事情,您就会看到构建 Ember 应用程序有何不同。
余烬之地的布局
在开始编写代码之前,了解 Ember.js 的工作原理以及了解构成 Ember 应用程序的移动部件非常重要。让我们看一下这些部分以及它们之间的关系。
模板
模板是定义用户界面的关键部分。正如我之前提到的,Handlebars 是 Ember 中使用的客户端库,在为应用程序创建 UI 时广泛使用该库提供的表达式。这是一个简单的例子:
<script type="text/x-handlebars"> <h2><strong>{{firstName}} {{lastName}}</strong></h2> </script>
请注意,表达式会混合到 HTML 标记中,并通过 Ember 动态更改页面上显示的内容。在这种情况下,{{firstName}} 和 {{lastName}} 占位符将被从应用检索的数据替换。
Handlebars 通过灵活的 API 提供强大的功能。了解它提供的功能对您来说非常重要。
路由
应用程序的路由器有助于管理应用程序的状态。
应用程序的路由器有助于管理应用程序的状态以及用户导航应用程序时所需的资源。这可能包括从模型请求数据、将控制器连接到视图或显示模板等任务。
您可以通过为应用程序中的特定位置创建一条路线来实现此目的。路由指定应用程序的各个部分以及与其关联的 URL。 URL 是 Ember 用于了解需要向用户呈现哪种应用程序状态的关键标识符。
App.Router.map( function() { this.route( 'about' ); // Takes us to "/about" });
路由的行为(例如:从模型请求数据)通过 Ember 路由对象的实例进行管理,并在用户导航到特定 URL 时触发。一个示例是从模型请求数据,如下所示:
App.EmployeesRoute = Ember.Route.extend({ model: function() { return App.Employee.find(); } });
在本例中,当用户导航到应用程序的“/employees”部分时,路由会向模型请求所有员工的列表。
模型
数据的对象表示。
模型是应用程序将使用的数据的对象表示。它可以是一个简单的数组或通过 Ajax 请求从 RESTful JSON API 动态检索的数据。 Ember 数据库提供了用于在应用程序中加载、映射和更新数据到模型的 API。
控制器
控制器通常用于存储和表示模型数据和属性。它们就像代理一样,使您可以访问模型的属性并允许模板访问它们以动态渲染显示。这就是模板始终连接到控制器的原因。
要记住的主要事情是,当模型检索数据时,您将使用控制器以编程方式将该数据公开给应用程序的不同部分。虽然模型和控制器看起来紧密耦合,但事实上,模型本身并不知道稍后将使用它们的控制器。
您还可以存储需要保留但不需要保存到服务器的其他应用程序属性。
观看次数
Ember.js 中的视图旨在管理围绕用户交互的事件,并将其转换为在应用程序中有意义的事件。因此,如果用户单击按钮来删除员工,则视图负责解释本机浏览器单击事件并在应用程序当前状态的上下文中对其进行适当处理。
命名约定
Ember.js 帮助最大程度地减少所需代码量并在幕后为您处理事务的方法之一是通过命名约定。定义和命名路由(和资源)的方式会影响控制器、模型、视图和模板的命名。例如,如果我创建一条名为“employees”的路线:
App.Router.map( function() { this.resource( 'employees' ); });
然后我会命名我的组件,如下所示:
- 路由对象: App.EmployeesRoute
- 控制器: App.EmployeesController
- 模型: App.Employee
- 视图: App.EmployeesView
- 模板: 员工
使用此命名约定有双重目的。首先,它为您提供了类似组件之间的语义关系。其次,Ember 可以自动创建可能不存在的必要对象(例如:路由对象或控制器)并将它们连接起来以便在您的应用程序中使用。这就是我前面提到的“魔力”。事实上,当您实例化 Application 对象时,这就是 Ember 在全局应用程序级别所做的具体操作:
var App = Ember.Application.create();
该单行创建对应用程序的路由器、控制器、视图和模板的默认引用。
- 路由对象: App.ApplicationRoute
- 控制器: App.ApplicationController
- 视图: App.ApplicationView
- 模板:应用程序
回到我上面创建的“employees”路由,当用户导航到应用程序中的“/employees”时,Ember 将查找以下对象:
- App.EmployeesRoute
- App.EmployeesController
- 员工模板
如果没有找到它们,它将创建每个实例的实例,但不会渲染任何内容,因为您尚未指定从中派生数据的模型或用于显示数据的模板。这就是命名约定如此重要的原因。它让 Ember 知道如何处理与特定路线相关的任务,而无需您手动进行连接。
请注意,在第一个示例中,我使用单数名称“Employee”来定义模型。这是故意的。 “员工”这个名称的本质决定了我可能会与 0 到多名员工一起工作,因此构建一个可以灵活返回一名员工或所有员工的模型非常重要。该模型的单一命名约定不是 Ember 的要求,因为模型本身不知道稍后将使用它们的控制器。因此,您可以灵活地命名它们,但为了保持一致性,坚持此约定将使您的代码管理变得更加容易。
此外,我选择使用 resource() 方法来定义我的路由,因为在这种情况下,我很可能使用嵌套路由来管理特定员工信息的详细信息页面。我们将在本系列后面讨论嵌套。
关键要点是,通过使用一致的命名方案,Ember 可以轻松管理将这些组件绑定在一起的挂钩,而无需通过大量代码显式定义关系。
项目网站上提供了 Ember 命名约定的完整详细信息,必读。
下一步:构建应用程序
在本系列的下一部分中,我们将深入研究代码来为我们的应用程序创建基础。
我们已经回顾了 Ember 的核心概念,并讨论了该框架的关键高级方面。在本系列的下一部分中,我们将深入研究代码来为我们的应用程序创建基础。在此期间,我想再次建议您开始查看 Handlebars 的文档,以了解表达式语法。另外,如果您真的迫不及待地想要进入 Ember,请继续关注 Tuts+ Premium,它将很快提供完整的课程,引导您构建基于 Ember 的应用程序!
正如我在本文开头指出的,Ember.js 核心团队领导 Yehuda Katz 和 Tom Dale 审查了此内容的准确性,并竖起大拇指。 Ember 团队已获批准!一会儿见!
拥抱 Ember.js 的世界的详细内容,更多请关注红帽云邮其它相关文章!