流星:使用集合时"TypeError: undefined is not an object"



我只是在尝试流星,一般来说,我在javascript中也不是很先进。我正在尝试使用模板从客户端的集合中显示对象的文本属性,但是我会在标题中提到的错误。我刚刚修改了默认的流星基础项目。

main.html:

<head>
  <title>Test</title>
</head>
<body>
  <section>
    {{> tweet}}
  </section>
</body>
<template name="tweet">
  <h1 class="mt-5">{{text}}</h1>
</template>

main.js

import { Template } from 'meteor/templating';
import { ReactiveVar } from 'meteor/reactive-var';
import './main.html';
import 'bootstrap/dist/js/bootstrap.bundle';
Tweets = new Mongo.Collection('tweets');
Template.tweet.onCreated(function tweetOnCreated() {
  var txt = Tweets.findOne().text;
  this.text = new ReactiveVar(txt);
});
Template.tweet.helpers({
  text() {
    return Template.instance().text.get();
  },
});

var txt = Tweets.findOne().text;有什么问题?我在这里对JavaScript有普遍的误解,还是此错误某种程度上与流星的工作方式有关?

这与流星的工作方式有关。

客户端启动时,它还没有任何数据。然后,客户端向服务器打开订阅(假设您仍然安装了默认的自动发布软件包,这是为您完成的),此后不久通过数据发送。

这是这里的"不久之后"部分。

在您的情况下,这意味着当Tweets.findOne()运行时,它还没有数据,因此没有文档可以从中读取text。因此错误。通过检查是否返回文档来防止错误:

Template.tweet.onCreated(function () {
  var doc = Tweets.findOne();
  if (doc) {
    this.text = new ReactiveVar(doc.text);
  }
});

如果您尝试此问题,则错误将消失,但仍然没有文本呈现。

因此,现在我们希望该代码部分在可用时再次运行。Blaze会在助手中自动执行此操作,但是您需要将其包装在autorun中:

Template.tweet.onCreated(function () {
  this.text = new ReactiveVar();
  this.autorun(() => {
    var doc = Tweets.findOne();
    if (doc) {
      this.text.set(doc.text);
    }
  });
});

我还将反应性var的创建移出了自动运行,因为我们只想创建一次,然后将其设置或获得其值。

或者,我前面提到的是帮助者自动自动运行。这意味着您可以在助手中找到推文,以简化模板:

Template.tweet.helpers({
  text() {
    var doc = Tweets.findOne();
    if (doc) return doc.text;
  },
});

更好,我们不再需要ReactiveVar,并且可以删除整个onCreated函数!

相关内容

最新更新