概述
Meteor 的模板语言 Spacebars
创建模板
控制处理
静态数据建立原型
请在工程中建立一个 module
pwd
~/Documents/GitHub/MeteorFactory
meteor create templates
删除自动生成的 html css js 文件
本文都在module中开发,并且只会关注module内的
/client
目录里面的事情
APP外壳
首先在 /client
目录中建立文件 main.html
并写入代码
<head>
<title>Microscope</title>
</head>
<body>
<div class="container">
<header class="navbar navbar-default" role="navigation">
<div class="navbar-header">
<a class="navbar-brand" href="/">Microscope</a>
</div>
</header>
<div id="main">
{{> postsList}}
</div>
</div>
</body>
这就是APP模板,其中 {{> postsList}} 标签就是 postsList的插入点
Meteor 模板
本示范是一个由很多帖子组成的,所以使用现成的模板
在/client
中创建目录 /templates
目录,这里放置各种模板,这样项目看起来整洁不少,并在 /templates
中建立 /posts
目录来放帖子相关的模板
Meteor 的查找文件功能,无论代码放到 client 目录的任何地方,Meteor都可以找到它并正确编译,所以不需要手动编写JavaScript或者CSS文件的调用路径,但是很容易
将所有文件放到一个目录下,这样项目的可维护和可读性被降低
在 client/templates/posts
目录中,创建 post_list.html
,内容为
<template name="postsList">
<div class="posts">
{{#each posts}}
{{> postItem}}
{{/each}}
</div>
</template>
再创建 post_item.html
,内容为
<template name="postItem">
<div class="post">
<div class="post-content">
<h3><a href="{{url}}">{{title}}</a><span>{{domain}}</span></h3>
</div>
</div>
</template>
其中 name="postsList"
属性,作用是告诉Meteor去跟踪这个模板的位置
在postsList
模板中,通过 {{#each}}…{{/each}}这个 Block Helper 去遍历一个 posts
对象,然后每次迭代过程都带有 postItem
的模板
postItem
模板中,使用标签 {{url}} {{title}}返回集合属性, {{domain}} 是调用模板对应的helper方法
SpaceBars
spaceBars 就是 HTML 加上 :
Inclusion: (也可以叫做 “Partial”), 通过 ){{> templateName}} 标记,简单告诉Meteor,这个部分会被模板替代
Expression: 比如 {{title}} 标记,要么是调用当前对象的属性,要么就是对应当前模板管理器中,定义的
help
方法,并返回方法值Block Helper: 在模板中控制流程的特殊标签,如 {{#each}}…{{/each}} 或者 {{#if}}…{{/if}}
进一步学习,参考 Spacebars文档
模板 Helper
Meteor的目的是让模板和逻辑分离,而这些模板本身不用做太复杂的事情。
让连接变得更流畅,一个模板需要一个helper,这些helper就是将数据通过模板加工后,显示到你们的面前。
模板的作用是显示或者轮询变量,而helper就是将值分配到每个变量,模板不是一个完整的Contoller,有一定MVC中 Contoller的作用
模板 Helper 的命名
简单粗暴,模板的 Helper 命名就是同模板本身同名的 .js
文件
模板使用
在目录 /client/templates/posts
下创建 posts_list.js
文件,构建一个helper
var postsData = [
{
title: 'Sogou Search',
url: 'https://www.sogou.com/'
},
{
title: 'Meteor',
url: 'http://meteor.com'
},
{
title: 'Discover Meteor 中文',
url: 'http://zh.discovermeteor.com/'
}
];
Template.postsList.helpers({
posts: postsData
});
这里使用模拟的静态数据来初始化到 postsData中。
然后通过 Template.postsList.helpers()
函数,建立 post
模板开回调刚刚定义的 postsData 数组
在模板文件 posts_list.html
中, 使用了这个 posts helper,使用过程是 **遍历postsData数组,并将里面的每个对象发送到postItem模板中
好了现在的执行效果为
domain Helper
建立一个 post_items.js
文件来包含 postItem
模板逻辑
Template.postItem.helpers({
domain: function () {
var a = document.createElement('a');
a.href = this.url;
return a.hostname;
}
});
运行效果为(每个条目的后面加入了 域名)
使用匿名函数简化了使用, 这个domain helper 方法,通过 JavaScript 来获取一个 url 地址 并返回一个域名,但是,当你点击这个域名的时候,发现是可以链接到具体网址的。
这是因为 post_list.html
模板中 {{#each}} 代码块,不只是遍历数组,还将在代码块范围内将 this的值赋给了被遍历的对象。
**也就是说,在{{#each}} 标记之间,每个 post 都可以通过 this 来依次访问,甚至延伸到模板 post_item.js
中
具体实现这个效果的原因是
创建一个空的锚 (a) HTML 标签,并存储在内存中
将href属性设置为当前的post URL,也就是this对象里面的URL
然后用 a 标签的特别属性 hostname 来返回 URL 的域名
Meteor的特性 动态代码重载
当你修改文件的时候,不需要手动刷新页面,浏览器就好自动重新加载
因为Meteor 跟踪了项目下所有的文件,当检测到一个变化的时候,就会自动刷新浏览器,甚至会在两个刷新动作之间保存APP的状态
Meteor对于文件的变动是非常敏感的,会带了一个额外的影响,很多时候,我们既需要文件变动,又需要让浏览器不要完全重新加载,这个问题先留在这里,后面给予解决