【问题标题】:Why is Meteor Template Object Not Defined?为什么没有定义 Meteor 模板对象?
【发布时间】:2015-04-11 07:04:31
【问题描述】:

我一直在关注一个教程做一个简单的论坛,最后把所有的代码放在一起后,它告诉我'模板未定义'

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('');
  }
};

这是我从流星得到的一些输出

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.

【问题讨论】:

  • fyi - 我遇到了同样的错误,因为我不小心将客户端文件夹之外的一个 clent 模板文件夹移到了根目录中。所以我从 /partners/partner.html 回到 /client/partners/partner.html 会更好。

标签: javascript meteor spacebars


【解决方案1】:

您看到错误的原因是您对Template 对象的第二次引用未指定为在客户端上显式运行,就像您对Template 的第一次引用一样。 Template 对象仅在客户端可用,详见 Meteor 文档的 this section。您只需将 if(Meteor.isClient){} 代码块的右括号降低到您的 Template.form.events 定义下方。

然而,这带来了应用程序结构的主题,以及在未来进一步开发应用程序时如何避免此类问题。如果您查看this documentation,强烈建议您将 JS 代码至少分成两个不同的位置,以避免将来遇到此类问题。我建议将您的 var Posts = new Meteor.Collection('posts'); 行移动到* server 文件夹 (name_of_app_directory/server) 内的 JS 文件中,并将所有其他 JS 代码移动到* client 文件夹内的 JS 文件中 ( name_of_app_directory/client)。这样,您就无需在代码中也包含 if(Meteor.isClient){} 块,并且不再有机会看到您遇到的错误。

另外,最后要考虑的事情。在定义模板events 对象时,定义它的方式与您已经定义模板helpers 对象(Template.form.events({...})) 的方式类似。有关这方面的更多信息,请参阅this documentation

【讨论】:

    【解决方案2】:

    您的代码有 2 个问题:

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

    • 正确的事件映射定义需要使用这个语法:Template.form.events({...}); not Template.form.events={...};

    【讨论】: