EmberJS 模板

作者 :邱信阳

EmberJS MVC 模板由 Nathan Totten、Thiago Santos 和 Xinyang Qiu 编写。

下载 EmberJS MVC 模板

EmberJS SPA 模板旨在帮助你快速开始使用 EmberJS 构建交互式客户端 Web 应用。

“单页应用程序” (SPA) 是 Web 应用程序的通用术语,该应用程序加载单个 HTML 页面,然后动态更新页面,而不是加载新页面。 初始页面加载后,SPA 通过 AJAX 请求与服务器通信。

显示标记为“客户端”和“服务器”的两个框的关系图。标记为 AJAX 的箭头从客户端转到服务器。标记为 H T M L 的箭头和标记为 J SON 的箭头从服务器转到客户端。

AJAX 并不是什么新鲜事,但如今有 JavaScript 框架可以更轻松地生成和维护大型复杂 SPA 应用程序。 此外,HTML 5 和 CSS3 使创建丰富的 UI 变得更加容易。

EmberJS SPA 模板使用 Ember JavaScript 库来处理来自 AJAX 请求的页面更新。 Ember.js使用数据绑定将页面与最新数据同步。 这样,就不必编写任何遍历 JSON 数据并更新 DOM 的代码。 而是将声明性属性放在 HTML 中,告知Ember.js如何呈现数据。

在服务器端,EmberJS 模板几乎与 KnockoutJS SPA 模板相同。 它使用 ASP.NET MVC 来提供 HTML 文档,并使用 ASP.NET Web API来处理来自客户端的 AJAX 请求。 有关模板这些方面的详细信息,请参阅 KnockoutJS 模板 文档。 本主题重点介绍 Knockout 模板和 EmberJS 模板之间的差异。

创建 EmberJS SPA 模板项目

单击上面的“下载”按钮下载并安装模板。 可能需要重启 Visual Studio。

“模板 ”窗格中,选择“ 已安装的模板 ”,然后展开 “Visual C# ”节点。 在 “Visual C#”下,选择“ Web”。 在项目模板列表中,选择“ ASP.NET MVC 4 Web 应用程序”。 给该项目命名,然后单击“确定”。

显示“新建项目”对话框的屏幕截图。已选择 A S P dot NET M V C 4 Web 应用程序模板。

“新建项目 ”向导中,选择“ Ember.js SPA 项目”。

显示“新建 A S P 点 NET M V C 4 项目”对话框的屏幕截图。已选择 Ember dot j s S P A 项目模板。

EmberJS SPA 模板概述

EmberJS 模板使用 jQuery、Ember.jsHandlebars.js的组合来创建流畅的交互式 UI。

Ember.js是使用客户端 MVC 模式的 JavaScript 库。

  • 以 Handlebars 模板化语言编写的 模板描述应用程序用户界面。 在发布模式下, Handlebars 编译器 用于捆绑和编译句柄栏模板。
  • 模型将它从服务器获取的应用程序数据存储 (ToDo 列表和 toDo 项) 。
  • 控制器存储应用程序状态。 控制器通常向相应的模板显示模型数据。
  • 视图转换应用程序中的基元事件,并将这些事件传递给控制器。
  • 路由器管理应用程序状态,使 URL 和模板保持同步。

此外,Ember Data library 还可用于同步通过 RESTful API) 和客户端模型从服务器获取 (JSON 对象。

EmberJS SPA 模板将脚本组织为八个层:

  • webapi_adapter.js,webapi_serializer.js:扩展 Ember Data 库以使用 ASP.NET Web API。
  • 脚本/helpers.js:定义新的 Ember Handlebars 帮助程序。
  • 脚本/app.js:创建应用并配置适配器和序列化程序。
  • Scripts/app/models/*.js:定义模型。
  • Scripts/app/views/*.js:定义视图。
  • Scripts/app/controllers/*.js:定义控制器。
  • Scripts/app/routes、Scripts/app/router.js:定义路由。
  • Templates/*.hbs:定义句柄栏模板。

让我们更详细地了解其中一些脚本。

模型

模型在 Scripts/app/models 文件夹中定义。 有两个模型文件:todoItem.js和todoList.js。

todo.model.js 定义 to-do 列表的客户端 (浏览器) 模型。 有两个模型类:todoItem 和 todoList。 在 Ember 中,模型是 DS 的子类。模型。 模型可以具有具有属性的属性:

todoItemId: attr('number'), 
title: attr('string')

模型可以定义与其他模型的关系:

todoList: DS.belongsTo('App.TodoList'),

模型可以具有绑定到其他属性的计算属性:

hasError: function () {
    var currentError = this.get("error");
    return !(currentError === '' || currentError === null);
}.property('error'),

模型可以具有观察程序函数,这些函数在观察到的属性更改时调用:

saveCheckbox: function () {
    if(this.get("isDirty")){
        if (this.get("todoItemId")) {
            App.store.commit();
        }
    }
}.observes('isDone'),

视图

视图在 Scripts/app/views 文件夹中定义。 视图转换应用程序 UI 中的事件。 事件处理程序可以回调控制器函数,或直接调用数据上下文。

例如,以下代码来自 views/TodoItemEditView.js。 它定义输入文本字段的事件处理。

App.TodoItemEditView = Em.TextField.extend({
    lastValue: '',
    focusIn: function (evt) {
        this.lastValue = this.get('parentView').templateData.view.content.get("title");
    },
    focusOut: function (evt) {
        this.changeContent();
    },

    insertNewline: function (evt) {
        $(evt.target).blur();
    },

    changeContent: function () {
        var todoItem = this.get('parentView').templateData.view.content;
        var newValue = todoItem.get("title");
        if (this.lastValue != newValue) {
            App.store.commit();
            this.lastValue = newValue;
        }
    }
});

控制器

控制器在 Scripts/app/controllers 文件夹中定义。 若要表示单个模型,请扩展 Ember.ObjectController

App.TodoItemController = Ember.ObjectController.extend({
});

控制器还可以通过扩展 Ember.ArrayController来表示模型的集合。 例如,TodoListController 表示对象的数组 todoList 。 控制器按 todoList ID 按降序排序:

App.TodoListController = Ember.ArrayController.extend({
    error: "",
    sortProperties: ['todoListId'],
    sortAscending: true,

    // ...

控制器定义一个名为 的 addTodoList函数,该函数创建一个新的 todoList 并将其添加到数组中。 若要查看此函数的调用方式,请在 Templates 文件夹中打开名为 todoListTemplate.html 的模板文件。 以下模板代码将按钮绑定到 addTodoList 函数:

<input type="button" {{action "addTodoList"}} class="isActive" value="Add Todo list"></input>

控制器还包含一个 error 属性,该属性包含一条错误消息。 下面是用于在todoListTemplate.html) (显示错误消息的模板代码:

<p class="error">{{error}}</p>

路由

Router.js定义要显示的路由和默认模板,设置应用程序状态,并将 URL 与路由匹配:

App.Router.map(function () {
    this.route("index", { path: "/" });
    this.route("about");
    this.route("todoList", { path: "/todo" });
});

TodoListRoute.js重写 setupController 函数加载 TodoListRoute 的数据:

App.TodoListRoute = Ember.Route.extend({
    setupController: function (controller, model) {
        controller.set('content', App.TodoList.find());
    }
});

Ember 使用命名约定来匹配 URL、路由名称、控制器和模板。 有关详细信息,请参阅 http://emberjs.com/guides/routing/defining-your-routes/ EmberJS 文档中的 。

模板

Templates 文件夹包含四个模板:

  • application.hbs:启动应用程序时呈现的默认模板。
  • about.hbs:“/about”路由的模板。
  • index.hbs:根“/”路由的模板。
  • todoList.hbs:“/todo”路由的模板。
  • _navbar.hbs:模板定义导航菜单。

应用程序模板的作用类似于母版页。 它包含页眉、页脚和“{{outlet}}”,用于根据路由插入其他模板。 有关 Ember 中的应用程序模板的详细信息,请参阅 http://guides.emberjs.com/v1.10.0/templates/the-application-template//

“/todoList”模板包含两个循环表达式。 外部循环为 {{#each controller}},内部循环为 {{#each todos}}。 以下代码显示了一个内置 Ember.Checkbox 视图、一个自定义 App.TodoItemEditView的 以及一个 deleteTodo 包含操作的链接。

{{view Ember.Checkbox checkedBinding="isDone"}}

{{view App.TodoItemEditView valueBinding="title" class="required" disabledBinding="isDone"}}

<a href="#" {{action "deleteTodo" on="click" target="view"}}>X</a>

Controllers HtmlHelperExtensions /HtmlHelperExtensions.cs 中定义的 类定义一个帮助程序函数,用于在Web.config文件中 将 debug 设置为 true 时缓存和插入模板文件。 此函数是从 Views/Home/App.cshtml 中定义的 ASP.NET MVC 视图文件调用的:

@if (HttpContext.Current.IsDebuggingEnabled)
{
    @Html.RenderEmber()
}
else
{
    @Scripts.Render("~/bundles/templates")
}

函数在没有参数的情况下调用,呈现 Templates 文件夹中的所有模板文件。 还可以指定子文件夹或特定模板文件。

当调试在 Web.config 中为 false 时,应用程序将包含捆绑项“~/bundles/templates”。 此捆绑包项使用 Handlebars 编译器库添加到 BundleConfig.cs 中:

if (!HttpContext.Current.IsDebuggingEnabled)
{
    bundles.Add(new Bundle("~/bundles/templates", 
        new EmberHandlebarsBundleTransform()).Include(
            "~/scripts/app/templates/*.hbs"
        ));
}