Это связано с тем, как работает Метеор.
Когда клиент запускается, у него еще нет данных. Затем клиент открывает подписки на сервере (при условии, что у вас все еще установлен пакет автоматической публикации по умолчанию, это сделано для вас), который вскоре отправляет данные.
Именно эта «вскоре после» часть является проблемой здесь.
В вашем случае это означает, что при запуске 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);
}
});
});
Я также переместил создание реактивной переменной из автозапуска, потому что мы хотим создать ее только один раз, а затем установить или получить ее значение.
В качестве альтернативы я упоминал ранее, что помощники автоматически запускаются. Это означает, что вы можете найти твит в помощнике, чтобы немного упростить ваш шаблон:
Template.tweet.helpers({
text() {
var doc = Tweets.findOne();
if (doc) return doc.text;
},
});
Еще лучше, нам больше не нужен ReactiveVar
, и мы можем удалить всю функцию onCreated
!