课程表

Meteor课程

工具箱
速查手册

Meteor 模版

当前位置:免费教程 » JS/JS库/框架 » Meteor

模版

为了更容易地进入 Meteor 的开发,我们将采用从外向内的方法来搭建项目。换句话说,我们将首先建立一个 HTML/JavaScript 的外壳,然后把它放到我们的项目里,内部细节处理稍后再说。

这意味着在本章中,我们只关注 /client 目录里面的事情。

让我们先在 /client 目录创建一个 main.html 文件,并写入以下代码:

  1. <head>
  2. <title>Microscope</title>
  3. </head>
  4. <body>
  5. <div class="container">
  6. <header class="navbar navbar-default" role="navigation">
  7. <div class="navbar-header">
  8. <a class="navbar-brand" href="/">Microscope</a>
  9. </div>
  10. </header>
  11. <div id="main">
  12. {{> postsList}}
  13. </div>
  14. </div>
  15. </body>

这是我们主要的 App 模板。在上面看到很多熟悉的 HTML 标签,除了这个 {{> postsList}} 标签,它是 postsList 模板的插入点,等一下我们就会说到。现在,先让我们创建更多的模板吧。

Meteor 模板

我们项目的核心是社会新闻网站,它是由一系列的帖子所组成的,而这正是我们要调用模板的原因。

我们先在 /client 里面创建一个 /templates 目录。这里用来放我们所有的模板,这样可以保持项目结构的清晰整洁,接着在 /templates 里面再创建 /posts 目录来存放与帖子相关的模板。

查找文件

Meteor 的强大之处在于文件的查找。无论你把代码文件放在 /client 目录下的任何地方,Meteor 都可以找到它并且正确地进行编译。这意味着你永远都不需要手动编写 JavaScript 或 CSS 文件的调用路径。

这也意味着你可能会把所有的文件放在同一目录,甚至所有的代码放在同一个文件。但由于 Meteor 会把一切的代码都编译到一个压缩的文件里面,因此我们更偏向于把项目弄得井井有条,使用更整洁的文件结构,提高项目的可读性。

接下来我们开始创建第二个模板。在 client/templates/posts 目录中,创建 posts_list.html :

  1. <template name="postsList">
  2. <div class="posts">
  3. {{#each posts}}
  4. {{> postItem}}
  5. {{/each}}
  6. </div>
  7. </template>

post_item.html

  1. <template name="postItem">
  2. <div class="post">
  3. <div class="post-content">
  4. <h3><a href="{{url}}">{{title}}</a><span>{{domain}}</span></h3>
  5. </div>
  6. </div>
  7. </template>

注意模板的 name="postsList" 属性,它的作用是告诉 Meteor 去根据这个名称来跟踪这个模板的位置。(注意的是实际文件的文件名不相关。)

是时候来介绍 Meteor 的模板系统 Spacebars 了。Spacebar 就是简单的 HTML 加上三件事情:Inclusion (有时也称作 “partial”)、ExpressionBlock Helper

Inclusion :通过 {{> templateName}} 标记,简单直接地告诉 Meteor 这部分需要用相同名称的模板来取代(在我们的例子中就是 postItem )。

Expression :比如 {{title}} 标记,它要么是调用当前对象的属性,要么就是对应到当前模板管理器中定义的 helper 方法,并返回其方法值(后面会详细讨论)。

Block Helper :在模板中控制流程的特殊标签,如 {{#each}}…{{/each}}{{#if}}…{{/if}}

进一步学习

有了这些知识,我们就可以很容易去理解了。

首先,在 postsList 模板里,我们通过 {{#each}}…{{/each}} Block Helper 去遍历一个 posts 对象。然后,每次迭代我们去包含 postItem 模板。

这个 posts 对象来自哪里?好问题。它实际上是一个 模板 helper,你可以想象它是动态值的占位符(placeholder)。

postItem 这个模板本身相当简单。它只使用三个标签: {{url}}{{title}} 都返回其集合的属性,而 {{domain}} 则调用模板对应的 helper 方法。

模板 Helper

到目前为止我们已经学会了使用 Spacebars ,这只是在 HTML 的基础上多几个标签而已。不像其他语言如 PHP (甚至常规 HTML 页面,还包含了 JavaScript), Meteor 只是让模板和逻辑进行分离,而这些模板本身并不需要做很多复杂的事情。

为了让连接变得更流畅,一个模板需要 helper。你可以想象这些 helper 就是厨师用食材(你的数据)烹饪好佳肴(模板),再由服务员端到你面前。

换句话说,模板的作用局限于显示或循环变量,而 helper 则扮演着一个相当重要的角色:把值分配给每个变量。

Contoller 控制器?

我们也许会情不自禁地认为包含所有模板 helper 的文件是个 controller(控制器)。但这是很模糊的,因为 controller (至少在 MVC 情况下)通常有些不同的作用。

所以我们决定远离那个术语,在谈论关于模板涉及的 JavaScript 代码时,就简单地称为“模板的 helper”或是“模板的逻辑”。

为简单起见,我们将采用与模板同名的方式来命名包含其 helper 的文件,区别是 .js 扩展名。那好让我们马上在 /client/templates/posts 目录下创建 posts_list.js 文件,开始构建我们第一个 helper:

  1. var postsData = [
  2. {
  3. title: 'Introducing Telescope',
  4. url: 'http://sachagreif.com/introducing-telescope/'
  5. },
  6. {
  7. title: 'Meteor',
  8. url: 'http://meteor.com'
  9. },
  10. {
  11. title: 'The Meteor Book',
  12. url: 'http://themeteorbook.com'
  13. }
  14. ];
  15. Template.postsList.helpers({
  16. posts: postsData
  17. });

如果你运行是正确的,你现在应该在浏览器中看到这样的画面:

我们刚刚在做两件事情。首先我们放置一些虚拟的基本数据到 postsData 数组中。原本数据应该是来自数据库的,但由于我们还没有学习到该怎么做(下一章揭晓),所以我们先通过使用静态数据来“作弊”。

然后,我们使用的是 Meteor 的 Template.postsList.helpers() 函数,建立了 posts 模板 helper 来返回刚刚定义的 postsData 数组。

如果你记得,现在我们在 postsList 模板中使用这个 posts helper:

  1. <template name="postsList">
  2. <div class="posts">
  3. {{#each posts}}
  4. {{> postItem}}
  5. {{/each}}
  6. </div>
  7. </template>

定义 posts helper 就就让我们的模板可以使用它,所以模板就可以遍历 postsData 数组并将里面的每个对象发送到 postItem 模板中。

添加了基本的 post 列表模板和静态数据

关于 domain Helper

类似地,我们现在创建一个 post_item.js 文件来包含 postItem 模板的逻辑:

  1. Template.postItem.helpers({
  2. domain: function() {
  3. var a = document.createElement('a');
  4. a.href = this.url;
  5. return a.hostname;
  6. }
  7. });

这一次我们 domain helper 的值不再是一个数组,而是一个匿名函数。相比起我们之前简化的虚拟数据的例子,这种模式更为常见(而且更有用)。

这个 domain helper 方法通过 JavaScript 来获取一个 URL 地址并返回其域名。但是它一开始是从哪里获得 URL 地址呢?

为了回答这个问题,我们需要回到我们的 posts_list.html 模板。{{#each}} 代码块不仅遍历我们数组,它还在代码块范围内将 this 的值赋予被遍历的对象

这意味着在 {{#each}} 标记之间,每个 post 都可以通过 this 依次访问,并且一直延伸到模板 helper(post_item.js)中。

我们现在明白了为什么 this.url 会返回当前 post 的 URL。而且,如果我们在 post_item.html 模板里面使用 {{title}}{{url}},Meteor 就会知道需要去调用 this.titlethis.url 去返回我们想要的正确值。

设置 postItemdomain helper

神奇的 JavaScript

尽管这对于 Meteor 来说并不特别,这里会简单解释一下上面“神奇的 JavaScript 代码”。首先,我们创建一个空的锚(a)HTML 标签并储存在内存中。

然后我们将其 href 属性设置为当前 post 的 URL (正如我们刚刚讲到的,this 在 helper 中正是当前被操作的对象)。

最后,我们利用 a 标签的特别的 hostname 属性来返回 URL 的域名。

如果你正确地紧跟着我们的进度,这时候你就会在浏览器中看到一个 post 列表。但这个列表只是调用了静态数据,它没有利用到 Meteor 实时性的特点。我们将在下一章向你展示该如何去修改!

动态代码重载

你可能已经注意到,当你修改文件的时候,不需要手动刷新页面,浏览器就会自动重新加载。

这是因为 Meteor 跟踪了项目目录下的所有文件,当检测到其中一个文件发生改变,它就会自动刷新你的浏览器。

Meteor 的动态代码重载是相当智能的,它甚至可以在两个刷新动作之间保存你的 App 状态。

模版

为了更容易地进入 Meteor 的开发,我们将采用从外向内的方法来搭建项目。换句话说,我们将首先建立一个 HTML/JavaScript 的外壳,然后把它放到我们的项目里,内部细节处理稍后再说。

这意味着在本章中,我们只关注 /client 目录里面的事情。

让我们先在 /client 目录创建一个 main.html 文件,并写入以下代码:

  1. <head>
  2. <title>Microscope</title>
  3. </head>
  4. <body>
  5. <div class="container">
  6. <header class="navbar navbar-default" role="navigation">
  7. <div class="navbar-header">
  8. <a class="navbar-brand" href="/">Microscope</a>
  9. </div>
  10. </header>
  11. <div id="main">
  12. {{> postsList}}
  13. </div>
  14. </div>
  15. </body>

这是我们主要的 App 模板。在上面看到很多熟悉的 HTML 标签,除了这个 {{> postsList}} 标签,它是 postsList 模板的插入点,等一下我们就会说到。现在,先让我们创建更多的模板吧。

Meteor 模板

我们项目的核心是社会新闻网站,它是由一系列的帖子所组成的,而这正是我们要调用模板的原因。

我们先在 /client 里面创建一个 /templates 目录。这里用来放我们所有的模板,这样可以保持项目结构的清晰整洁,接着在 /templates 里面再创建 /posts 目录来存放与帖子相关的模板。

查找文件

Meteor 的强大之处在于文件的查找。无论你把代码文件放在 /client 目录下的任何地方,Meteor 都可以找到它并且正确地进行编译。这意味着你永远都不需要手动编写 JavaScript 或 CSS 文件的调用路径。

这也意味着你可能会把所有的文件放在同一目录,甚至所有的代码放在同一个文件。但由于 Meteor 会把一切的代码都编译到一个压缩的文件里面,因此我们更偏向于把项目弄得井井有条,使用更整洁的文件结构,提高项目的可读性。

接下来我们开始创建第二个模板。在 client/templates/posts 目录中,创建 posts_list.html :

  1. <template name="postsList">
  2. <div class="posts">
  3. {{#each posts}}
  4. {{> postItem}}
  5. {{/each}}
  6. </div>
  7. </template>

post_item.html

  1. <template name="postItem">
  2. <div class="post">
  3. <div class="post-content">
  4. <h3><a href="{{url}}">{{title}}</a><span>{{domain}}</span></h3>
  5. </div>
  6. </div>
  7. </template>

注意模板的 name="postsList" 属性,它的作用是告诉 Meteor 去根据这个名称来跟踪这个模板的位置。(注意的是实际文件的文件名不相关。)

是时候来介绍 Meteor 的模板系统 Spacebars 了。Spacebar 就是简单的 HTML 加上三件事情:Inclusion (有时也称作 “partial”)、ExpressionBlock Helper

Inclusion :通过 {{> templateName}} 标记,简单直接地告诉 Meteor 这部分需要用相同名称的模板来取代(在我们的例子中就是 postItem )。

Expression :比如 {{title}} 标记,它要么是调用当前对象的属性,要么就是对应到当前模板管理器中定义的 helper 方法,并返回其方法值(后面会详细讨论)。

Block Helper :在模板中控制流程的特殊标签,如 {{#each}}…{{/each}}{{#if}}…{{/if}}

进一步学习

有了这些知识,我们就可以很容易去理解了。

首先,在 postsList 模板里,我们通过 {{#each}}…{{/each}} Block Helper 去遍历一个 posts 对象。然后,每次迭代我们去包含 postItem 模板。

这个 posts 对象来自哪里?好问题。它实际上是一个 模板 helper,你可以想象它是动态值的占位符(placeholder)。

postItem 这个模板本身相当简单。它只使用三个标签: {{url}}{{title}} 都返回其集合的属性,而 {{domain}} 则调用模板对应的 helper 方法。

模板 Helper

到目前为止我们已经学会了使用 Spacebars ,这只是在 HTML 的基础上多几个标签而已。不像其他语言如 PHP (甚至常规 HTML 页面,还包含了 JavaScript), Meteor 只是让模板和逻辑进行分离,而这些模板本身并不需要做很多复杂的事情。

为了让连接变得更流畅,一个模板需要 helper。你可以想象这些 helper 就是厨师用食材(你的数据)烹饪好佳肴(模板),再由服务员端到你面前。

换句话说,模板的作用局限于显示或循环变量,而 helper 则扮演着一个相当重要的角色:把值分配给每个变量。

Contoller 控制器?

我们也许会情不自禁地认为包含所有模板 helper 的文件是个 controller(控制器)。但这是很模糊的,因为 controller (至少在 MVC 情况下)通常有些不同的作用。

所以我们决定远离那个术语,在谈论关于模板涉及的 JavaScript 代码时,就简单地称为“模板的 helper”或是“模板的逻辑”。

为简单起见,我们将采用与模板同名的方式来命名包含其 helper 的文件,区别是 .js 扩展名。那好让我们马上在 /client/templates/posts 目录下创建 posts_list.js 文件,开始构建我们第一个 helper:

  1. var postsData = [
  2. {
  3. title: 'Introducing Telescope',
  4. url: 'http://sachagreif.com/introducing-telescope/'
  5. },
  6. {
  7. title: 'Meteor',
  8. url: 'http://meteor.com'
  9. },
  10. {
  11. title: 'The Meteor Book',
  12. url: 'http://themeteorbook.com'
  13. }
  14. ];
  15. Template.postsList.helpers({
  16. posts: postsData
  17. });

如果你运行是正确的,你现在应该在浏览器中看到这样的画面:

我们刚刚在做两件事情。首先我们放置一些虚拟的基本数据到 postsData 数组中。原本数据应该是来自数据库的,但由于我们还没有学习到该怎么做(下一章揭晓),所以我们先通过使用静态数据来“作弊”。

然后,我们使用的是 Meteor 的 Template.postsList.helpers() 函数,建立了 posts 模板 helper 来返回刚刚定义的 postsData 数组。

如果你记得,现在我们在 postsList 模板中使用这个 posts helper:

  1. <template name="postsList">
  2. <div class="posts">
  3. {{#each posts}}
  4. {{> postItem}}
  5. {{/each}}
  6. </div>
  7. </template>

定义 posts helper 就就让我们的模板可以使用它,所以模板就可以遍历 postsData 数组并将里面的每个对象发送到 postItem 模板中。

添加了基本的 post 列表模板和静态数据

关于 domain Helper

类似地,我们现在创建一个 post_item.js 文件来包含 postItem 模板的逻辑:

  1. Template.postItem.helpers({
  2. domain: function() {
  3. var a = document.createElement('a');
  4. a.href = this.url;
  5. return a.hostname;
  6. }
  7. });

这一次我们 domain helper 的值不再是一个数组,而是一个匿名函数。相比起我们之前简化的虚拟数据的例子,这种模式更为常见(而且更有用)。

这个 domain helper 方法通过 JavaScript 来获取一个 URL 地址并返回其域名。但是它一开始是从哪里获得 URL 地址呢?

为了回答这个问题,我们需要回到我们的 posts_list.html 模板。{{#each}} 代码块不仅遍历我们数组,它还在代码块范围内将 this 的值赋予被遍历的对象

这意味着在 {{#each}} 标记之间,每个 post 都可以通过 this 依次访问,并且一直延伸到模板 helper(post_item.js)中。

我们现在明白了为什么 this.url 会返回当前 post 的 URL。而且,如果我们在 post_item.html 模板里面使用 {{title}}{{url}},Meteor 就会知道需要去调用 this.titlethis.url 去返回我们想要的正确值。

设置 postItemdomain helper

神奇的 JavaScript

尽管这对于 Meteor 来说并不特别,这里会简单解释一下上面“神奇的 JavaScript 代码”。首先,我们创建一个空的锚(a)HTML 标签并储存在内存中。

然后我们将其 href 属性设置为当前 post 的 URL (正如我们刚刚讲到的,this 在 helper 中正是当前被操作的对象)。

最后,我们利用 a 标签的特别的 hostname 属性来返回 URL 的域名。

如果你正确地紧跟着我们的进度,这时候你就会在浏览器中看到一个 post 列表。但这个列表只是调用了静态数据,它没有利用到 Meteor 实时性的特点。我们将在下一章向你展示该如何去修改!

动态代码重载

你可能已经注意到,当你修改文件的时候,不需要手动刷新页面,浏览器就会自动重新加载。

这是因为 Meteor 跟踪了项目目录下的所有文件,当检测到其中一个文件发生改变,它就会自动刷新你的浏览器。

Meteor 的动态代码重载是相当智能的,它甚至可以在两个刷新动作之间保存你的 App 状态。

转载本站内容时,请务必注明来自W3xue,违者必究。
 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号