繁体   English   中英

流星:使用集合时出现“ TypeError:未定义不是对象”

[英]Meteor: “TypeError: undefined is not an object” when using collection

我只是在尝试Meteor,而且我对Javascript的总体了解也不高。 我正在尝试使用模板在客户端的集合中显示对象的文本属性,但是出现标题中提到的错误。 我刚刚修改了默认的Meteor基础项目。

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有一个普遍的误解吗?还是这个错误与Meteor的工作方式有某种关系?

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

客户端启动时,它还没有任何数据。 然后,客户端使用服务器打开订阅(假设您仍然安装了默认的自动发布程序包,此操作已为您完成),此后不久将通过数据发送。

这就是“此后不久”的问题。

在您的情况下,这意味着当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函数!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM