2014-04-03 2 views
0

Скажем, у меня есть помощник, которому нужно вернуть название статьи.Метеор занимает несколько раз, чтобы сделать успешную базу данных.

<template name="articleList"> 
    <span>{{title}}</span> 
</template> 

Template.articleList.title = function() { 
    return Articles.findOne({author: "Billy Bob"}).title 
} 

Я часто получаю сообщение об ошибке «Невозможно прочитать свойство неопределенной». Поэтому, когда я пытаюсь отлаживать его, как этот

Template.articleList.title = function() { 
    console.log(Articles.findOne({author: "Billy Bob"})) 
} 

Журнал будет сказать

undefined 
undefined 
Object[0] 

Так он работает только на третий раз. Я думаю, что это, вероятно, плохой код где-то в моем маршрутизаторе или где-то еще, но я не знаю, что это такое. Какие-либо предложения?

+0

Это происходит потому, что в начале, когда клиент загружается в первый раз, у него пока нет данных. В следующий раз он будет подписаться на публикацию. И тогда он начнет получать данные. Узнайте больше о знании, когда подписка готова здесь: http://docs.meteor.com/#meteor_subscribe – imslavko

+0

Так что вы говорите, что это то, что нельзя отменить? Потому что это не происходит для всех моих помощников. Некоторым помощникам нужна только одна попытка, а другим - две. – Nubby

+0

Ваши другие помощники могут работать с курсорами от 'find', а не от документов из' findOne'. – sbking

ответ

1

Вы должны проверить, что документ уже загружен подписки. Попробуйте это:

<template name="articleList"> 
    <span>{{title}}</span> 
</template> 
Template.articleList.title = function() { 
    var doc = Articles.findOne({author: "Billy Bob"}); 
    return doc && doc.title; 
}; 

Причина заключается в том, что если клиент еще не получил этот документ через DDP, то findOne вызов возвратит null. При попытке вызвать null.title вы получите сообщение об ошибке.

+0

Так что это не то, что можно исправить. Думаю, – Nubby

+0

Вам просто нужно понять, как работает Метеор. Ваши подписки загружаются в фоновом режиме по DDP. Это позволяет использовать синхронный интерфейс коллекции на стороне клиента, вместо того, чтобы иметь кучу асинхронных обратных вызовов. Когда вы используете 'findOne', вам нужно помнить, что связанный результат не может быть загружен в minimongo. Вы всегда можете «найти» с опцией 'limit', установленной в 1. Это возвращает реактивный * курсор *, а не * документ *. Вы также можете всегда выполнять вызов пользовательского метода сервера, но это не будет реактивным. – sbking

+0

Хорошо, спасибо за объяснение. – Nubby

0

Попробуйте это:

<template name="articleList"> 
    <span>{{article.title}}</span> 
</template> 

Template.articleList.article = function() { 
    return Articles.findOne({author: "Billy Bob"}); 
} 
+0

Я знаю, что это сработает, но мой вопрос больше о том, почему требуется три раза, чтобы вернуться к чтению. – Nubby

+0

@imlavko объяснил, что в комментарии к вашему вопросу –

Смежные вопросы