开发者问题收集

为什么 Meteor 模板对象未定义?

2015-02-11
3874

我一直在按照教程制作一个简单的论坛,在最终将所有代码整合在一起后,它告诉我“模板未定义”

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个回答

您的代码存在 2 个问题:

  • 模板定义在服务器上不可用,因此您需要将 Template.form 定义包装在 Meteor.isClient 条件中,或者更好的是,使用 clientserver 目录分离您的代码。

  • 正确的事件映射定义需要使用此语法: Template.form.events({...}); 而不是 Template.form.events={...};

saimeunt
2015-02-11

您看到错误的原因是因为您对 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({...}) ) 类似的方式定义它。有关此内容的更多信息,请参阅 此文档

Keith Dawson
2015-08-10