前回のチュートリアルでは、Ember.Object
を使用してモデルを定義し、データセットを操作する方法を紹介しました。このセクションでは、Ember が Handlebars テンプレート フレームワークを使用してアプリのユーザー インターフェイスを定義する方法を詳しく見ていきます。
ほとんどのサーバーサイド開発者は、テンプレートを使用して動的に設定されるタグを定義することに慣れています。 ASP.NET、ColdFusion、PHP、または Rails を使用したことがある場合は、私が何を言っているのか確実に理解できるでしょう。
JavaScript クライアント側テンプレートは、特にデスクトップに似たエクスペリエンスを構築することに重点を置いているため、最近人気が高まり始めています。これは、より多くの処理がクライアント側で行われ、データは主にサーバー側の API リクエストを通じて取得されることを意味します。
少し前に jQuery テンプレート プラグインが最初にリリースされたときに、クライアント側のテンプレートについて書いたことを覚えています。 3 年近く経った今でも、この記事は私のブログで最も読まれている投稿であり、クライアント側のテンプレートに対する関心がいかに高いかを示しています。それ以来、他の多くのフレームワークがリリースされ、豊富な機能を提供し、コミュニティをサポートしてきました。 Handlebars は最も人気のあるオプションの 1 つで、テンプレートのニーズに合わせて Ember プロジェクトによって選択されたフレームワークです。 Handlerbars は Ember.js の共同創設者でありコア チーム メンバーの Yehuda Katz によって作成されたため、これは当然のことです。ただし、テンプレート フレームワーク間の比較を行うつもりはないことに注意してください。Ember.js がデフォルトで使用するものであるため、Handelbar に厳密に焦点を当てます。
前の記事では、コード内の非常に基本的なテンプレートをいくつか示しました。
リーリー目立つ 2 つの点は、スクリプト タグの型宣言と中かっこです。これらは、ハンドルバーが動作する式の区切り文字として機能します。これは非常に一般的な構文であり、後ほど詳しく説明します。また、Ember テンプレートを構築するときに一貫して使用します。
どのテンプレートでも最初に必要なのは、スクリプト タグの定義です。ほとんどの人は、JavaScript ライブラリをロードするためにスクリプト タグを定義したことがあるでしょう。実際、これはすでに実行されており、ハンドルバーを Ember プロジェクトにロードしています:
リーリーこれを使用してテンプレートを定義するのとは少し異なります。まず、「text/x-handlebars」の
type 属性を指定します。ブラウザはこの type
を無視しますが、検査に使用できるテキストを残し、Ember がアプリケーション内のテンプレートを認識できるようにします。さらに、Ember は「data-template-name」と呼ばれるデータ属性を使用します。これを使用して、アプリケーションの特定の部分をテンプレートに関連付けます。たとえば、次の宣言は「employee」という名前のテンプレートを定義します。
リーリー
アプリケーションが起動すると、Ember は
type="text/x-handlebars
Ember.TEMPLATES を使用して、特定のルートに何がレンダリングされるかを確認します。これが、Ember の命名規則に従うことが非常に重要である理由です。上記の例では、このテンプレートは自動的に従業員ルートに関連付けられます繰り返しになりますが、これらの命名規則によって開発がいかに容易になるかは、どれだけ強調してもしすぎることはありません。
Ember は URL に基づいて、使用するリソースとレンダリングするテンプレートを決定します。 URL「/profile」のプロフィールページがあるとします。その URL に固有のリソース (ルート オブジェクトなど) を読み込む profile
というリソースがあり、同じ名前のテンプレートもあります。 Ember シリーズのパート 2 でリソースの定義とオブジェクトのルーティングについて説明しました。何を言っているのかよくわからない場合は、必ずそこに戻って知識を更新してください。
その URL にアクセスすると、Ember はこれらのリソースをロードし、定義したテンプレートを解析する必要があることを認識します。これは、「/profile」に移動するため、profile
で定義されたリソースをロードし、
ルート:
プロファイルルート
还需要注意的是,如果您声明的模板没有 data-template-name
属性,Ember 将假定它是应用程序范围的模板 - 通常用作站点范围模板来创建用户界面元素,例如页眉、页脚和导航。如果您没有为应用程序甚至资源(例如 URL)显式定义模板,Ember 会自动为您执行此操作,以确保应用程序的稳定性和一致性。
下一步是包含您的标记和用于表示数据的分隔表达式。表达式通过双花括号进行分隔,这使得它们可以通过从控制器传递的数据轻松识别和解析。这是一个例子:
<script type="text/x-handlebars"> <h2><strong>{{firstName}} {{lastName}}</strong></h2> </script>
在这种情况下,{{firstName}}
和 {{lastName}}
表达式将被 Ember 解析并替换为实际数据。此外,Ember 设置了观察者,以便当您的数据发生变化时,您的模板会自动更新,并将更新反映给应用程序的用户。
到目前为止,我已经向您展示了一个非常简单的示例,但要点是:
这为您构建用户界面的方式提供了很大的灵活性。让我们继续看看可用的功能。
请记住,Ember 利用了 Handlebars,因此您可以在此处访问其完整的表达式。为了使几乎任何东西变得有用,条件表达式是必须的;车把提供了相当多的选择。
假设我有一个如下所示的 JSON 数据集:
"items": [{ "title": "Tearable Cloth Simulation in JavaScript", "url": "http://codepen.io/stuffit/pen/KrAwx", "id": 5592679, "commentCount": 20, "points": 127, "postedAgo": "1 hour ago", "postedBy": "NathanKP" }, { "title": "Netflix now bigger than HBO", "url": "http://qz.com/77067/netflix-now-bigger-than-hbo/", "id": 5592403, "commentCount": 68, "points": 96, "postedAgo": "2 hours ago", "postedBy": "edouard1234567" }
如果我想确保 title
数据可用,我可以使用 #if
表达式添加条件“if”语句:
{{#if item.title}} <li>{{item.title}} - {{item.postedAgo}} by {{item.postedBy}}</li> {{/if}}
这会检查 item.title
是否未定义,并继续处理 title
、postedAgo
和 postedBy
数据表达式的后续表达式。
由于该数据集包含多个“记录”,因此可以安全地假设我们可能希望循环 item
的每个元素。这就是 {{#each}}
表达式发挥作用的地方。它允许您枚举对象列表。因此,再次记住模板是标记和 Handlebars 表达式的组合,我们可以使用 #each
表达式来循环遍历 Ember 模型对象中可用的每个项目。请记住,Ember 模型是从控制器派生的,控制器通过 Ember 的命名约定与模板关联。
<ul> {{#each item in model}} {{#if item.title}} <li>{{item.title}} - {{item.postedAgo}} by {{item.postedBy}}</li> {{/if}} {{/each}} </ul>
这会渲染出类似于以下内容的内容:
<ul> <li>Tearable Cloth Simulation in JavaScript - 1 hour ago by NathanKP</li> <li>Netflix now bigger than HBO - 2 hours ago by edouard1234567</li> <li>Fast Database Emerges from MIT Class, GPUs and Student's Invention - 33 minutes ago by signa11</li> <li> Connecting an iPad retina LCD to a PC - 6 hours ago by noonespecial</li> </ul>
显着的优势是 Ember 隐含的观察者规范,它将在更新时更新您的数据。
如果您的条件表达式需要更复杂,您将需要创建一个计算属性。这允许您基于可以将复杂代码条件应用于数据的方法创建属性。假设我只想显示标题为“JavaScript 中的可撕裂布料模拟”的数据。我需要设置几件事:
我需要做的第一件事是创建新的控制器,它将包装循环的每个项目并在其中创建计算属性:
App.TitleController = Ember.ObjectController.extend({ titleMatch: function() { return this.get('title') === "Tearable Cloth Simulation in JavaScript"; }.property() });
查看代码,我们对 Ember.ObjectController
进行子类化以创建控制器。这是控制器,它将包装模板中循环的每个项目。接下来,我们创建一个名为 titleMatch
的方法,它使用 get()
方法来拉回当前标题,将其与我定义的文本进行比较,然后返回一个布尔值。最后,调用 Ember property() 方法将 titleMatch 方法定义为计算属性。
完成此操作后,我们将更新模板的 {{#each}}
表达式,以使用我们创建的新控制器来表示每个项目。这是通过使用 itemController 指令来完成的。需要理解的关键一点是 itemController
是 Ember 中的一个关键短语,旨在将控制器与模板的项目关联起来。不要将其与实际的控制器名称混淆(就像我最初所做的那样)。控制器名称分配给 itemController
,如下所示:
<ul> {{#each item in model itemController="title"}} {{#if titleMatch}} <li>{{foo.title}} - {{foo.postedAgo}} by {{foo.postedBy}}</li> {{/if}} {{/each}} </ul>
同样,命名约定规定,在模板中分配名称时,我们使用小写。在本例中,我们将 TitleController
分配给 itemController
。
现在,当循环每个项目时,计算属性 titleMatch
用于评估标题并在匹配时显示数据。
创建动态模板不仅仅是吐出文本。有时,UI 的外观需要受到正在处理的数据的影响。显示图像或建立链接就是很好的例子。
将数据绑定到元素需要使用特殊的 Ember 助手来帮助定义属性的上下文,并确保在数据更改时正确更新属性。对于元素属性,{{bindAttr}}
帮助器用于填充属性的值。如果我们需要动态指定图像的 URL,我们将使用以下语法:
<img {{bindAttr src="logoUrl"}} alt="残り火を抱きしめる: パート 4">
对于不接收值的属性也可以这样做,例如disabled
:
<input type="checkbox" {{bindAttr disabled="isAdministrator"}}>
在这种情况下, isAdminstrator
可以是基于控制器中的方法的计算属性,或者只是一个普通的对象属性,为您在定义禁用复选框的条件方面提供了很大的灵活性。这种灵活性也适用于定义类名。如果我想使用条件语句来定义是否应将类应用于我的元素,我可以使用以下代码:
<div {{bindAttr class="isUrgent"}}> Warning! </div>
根据布尔状态,我的标记将是:
<div {{bindAttr class="is-urgent"}}> Warning! </div>
对于 true
条件,或:
<div> Warning! </div>
对于 false
条件。请注意,当我为该类指定 isUrgent
时,Ember 对该名称进行了 dasher 处理,并将该类呈现为 is-urgent
。如果您希望根据结果指定自己的类,可以使用类似于三元语句的条件表达式:
<div {{bindAttr class="isUrgent:urgent:normal"}}>
这将根据 isUrgent
的条件值返回该类的 urgent
或 normal
。
模板将成为用户界面的基础,因此花时间阅读 Ember 和 Handlebars 站点上的文档以充分了解它们的整体功能非常重要。即使您不使用 Ember,Handlebars 也是一个适合您日常使用的出色框架,并且值得投资学习如何使用它。
Gabriel Manricks 在 Nettuts+ 上编写了一篇关于 Handlebars 的精彩教程,您可以使用它来加快框架的速度。
以上が残り火を抱きしめる: パート 4の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。