为什么 Meteor 模板对象未定义?
我一直在按照教程制作一个简单的论坛,在最终将所有代码整合在一起后,它告诉我“模板未定义”
forum.html 的代码
<head>
<title>Forum</title>
</head>
<body>
{{> form}}
{{> posts}}
</body>
<template name="posts">
<h1>Posts</h1>
<ul>
{{#each posts}}
<li>
<h3>{{title}}</h3>
<p>{{body}}</p>
</li>
{{/each}}
</ul>
</template>
<template name="form">
<form>
<label>Post Title:
<input type="text" id="title" />
</label>
<label>Post Body:
<textarea id="body"></textarea>
</label>
<input type="submit" value="Submit" id="submit"/>
</form>
</template>
forum.js 的代码:
var Posts = new Meteor.Collection('posts');
if (Meteor.isClient) {
Template.posts.helpers({
Posts: function() {
return Posts.find();
}
});
}
Template.form.events = {
'click #submit': function(event){
event.preventDefault();
var title = $('#title').val();
var body = $('#body').val();
Posts.insert({
title: title,
body: body
});
$('#title, #body').val('');
}
};
这是我从 Meteor 获得的一些输出
W20150211-02:01:42.086(0)? (STDERR)
W20150211-02:01:42.088(0)? (STDERR) /home/ubuntu/.meteor/packages/meteor-tool/.1.0.40.1ef5dzv++os.linux.x86_64+web.browser+web.cordova/meteor-tool-os.linux.x86_64/dev_bundle/server-lib/node_modules/fibers/future.js:173
W20150211-02:01:42.088(0)? (STDERR) throw(ex);
W20150211-02:01:42.088(0)? (STDERR) ^
W20150211-02:01:42.091(0)? (STDERR) ReferenceError: Template is not defined
W20150211-02:01:42.091(0)? (STDERR) at app/forum.js:10:1
W20150211-02:01:42.091(0)? (STDERR) at app/forum.js:23:3
W20150211-02:01:42.091(0)? (STDERR) at /home/ubuntu/workspace/forum/.meteor/local/build/programs/server/boot.js:205:10
W20150211-02:01:42.092(0)? (STDERR) at Array.forEach (native)
W20150211-02:01:42.092(0)? (STDERR) at Function._.each._.forEach (/home/ubuntu/.meteor/packages/meteor-tool/.1.0.40.1ef5dzv++os.linux.x86_64+web.browser+web.cordova/meteor-tool-os.linux.x86_64/dev_bundle/server-lib/node_modules/underscore/underscore.js:79:11)
W20150211-02:01:42.092(0)? (STDERR) at /home/ubuntu/workspace/forum/.meteor/local/build/programs/server/boot.js:116:5
=> Exited with code: 8
=> Your application is crashing. Waiting for file change.
您的代码存在 2 个问题:
-
模板定义在服务器上不可用,因此您需要将
Template.form
定义包装在Meteor.isClient
条件中,或者更好的是,使用client
和server
目录分离您的代码。 -
正确的事件映射定义需要使用此语法:
Template.form.events({...});
而不是Template.form.events={...};
您看到错误的原因是因为您对
Template
对象的第二次引用未指定为在客户端上明确运行,就像您对
Template
的第一次引用一样。
Template
对象仅在客户端上可用,如 Meteor 文档的
此部分
中所述。您只需将
if(Meteor.isClient){
代码块的右括号放到
Template.form.events
定义下方即可。
然而,这引出了应用程序结构的主题,以及如何在将来进一步开发应用程序时避免此类问题。如果您查看
本文档
,强烈建议您将 JS 代码分成至少两个不同的位置,以避免将来遇到此类问题。我建议将您的
var Posts = new Meteor.Collection('posts');
行移动到顶级
server
文件夹 (
name_of_app_directory/server
) 内的 JS 文件中,并将所有其他 JS 代码移动到顶级
client
文件夹 (
name_of_app_directory/client
) 内的 JS 文件中。这样,您就无需在代码中包含
if(Meteor.isClient){
块,也不会再看到您遇到的错误。
此外,还有最后要考虑的事情。定义模板
events
对象时,请按照与已定义模板
helpers
对象 (
Template.form.events({...})
) 类似的方式定义它。有关此内容的更多信息,请参阅
此文档
。