2015-04-23 1 views
1

У меня есть коллекция в моем Метеор JS приложения:Метеор JS: Сроки доступа к MongoDB влияет на результат доступа

MenuItems = new Mongo.Collection('menu_items'); 

В моем файле шаблона Helper я получить доступ к этой коллекции:

Template.admin_menu_items.helpers({ 

    menuItems: function(){ 
    //return items from DB 
    console.log('inside menuItems'); 

    snapshot = MenuItems.find().fetch(); 

    console.log(snapshot); 

    return snapshot; 

    }, 
}); 

Тогда в моем файле HTML шаблон Я называю этот помощник:

{{#each menuItems}} 
    {{#each items}} 
    {{this}} 
    {{/each}} 

{{/each}} 

Тогда в моем шаблоне оказывается помощник обратного вызова себе фикция я снова получить доступ к этой коллекции:

Template.admin_menu_items.rendered = function(){ 

    console.log('Template.admin_menu_items.rendered'); 

    var snapshotRendered = MenuItems.find().fetch(); 
    // 
    console.log(snapshotRendered); 


} 

Если я обновить страницу, я получаю следующий результат:

inside menuItems     admin_m...4d3e6ec (line 9) 
[]         admin_m...4d3e6ec (line 13) 
Template.admin_menu_items.rendered admin_m...4d3e6ec (line 36) 
[]         admin_m...4d3e6ec (line 40) 
inside menuItems     admin_m...4d3e6ec (line 9) 
[Object { _id="nHZBfwAt64dwiPjCB", items=[3]}] 

То, что я хотел бы понять и спросить: почему это, что первый звонок до MenuItems.find().fetch() внутри вспомогательного элемента menuItems и первого вызова MenuItems.find().fetch() внутри обработанной шаблоном функции обратного вызова возвращает пустой массив [], когда в коллекции MenuItems уже есть документы внутри? ???

Это потому, что мой шаблон и шаблон вспомогательные файлы глубже в иерархии файлов и поэтому загружается раньше, чем мой menu_item.js файл, который создает переменную MenuItems по:

MenuItems = new Mongo.Collection('menu_items'); 

Как убедиться, что MongoDB вернет правильное количество документов с самого первоначального вызова или доступа к нему?

Большое спасибо

ответ

1

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

  1. Шаблона начинает строить себя без данных, поэтому помощник работает с пустым массивом
  2. шаблон достроен и делает, но без данных он тоже имеет пустой массив
  3. данные прибывают
  4. хелперного реактивно повторные показы с новыми данными, и возвращает полный массив

Решение этого, если вам нужны данные в обработанном обратном вызове, заключается в том, чтобы предотвратить запуск этого шаблона до поступления данных. Вы можете обработать это с помощью маршрутизатора, который ждет подписки, или путем проверки данных и только визуализации шаблона, когда количество элементов не равно нулю, или с помощью функции Template.subscribe и защиты вашего шаблона с помощью оператора if до тех пор, пока данные не будут готов.

На стороне записки, вы можете вернуть результат find() в вашем помощнике, а не find().fetch(), он будет работать так же в {{#each}} блоке, но с более мелкозернистой реакционной способности Blaze может перебрать сам курсор , Если, конечно, вам не нужен массив.

1

Как я могу гарантировать, что MongoDB будет возвращать правильное количество документов с самого первого вызова или доступа к ней делается ???

Ну, в духе метеорита ... У вас нет.

Все об Метере - реактивность. Вы не хотите, чтобы подождали для получения данных, чтобы начать рендеринг. Это означало бы, что ваш пользователь будет наблюдать за пустой страницей некоторое время, прежде чем увидеть какое-то действие, потому что отображение блоков страниц, ждет в темном забвении для получения полной информации.

Вместо этого вы идете на реактивность. Вы выполняете reactive computations, которые выполняются немедленно, тогда каждый раз, когда реактивные данные внутри них обновляются. Помощники - реактивные вычисления, монго-курсоры в Метеор - реактивные данные. Помощники запускаются изначально (возможно, ничего не возвращает, потому что данные еще не наступили), то каждый раз, когда появляются какие-то новые данные.

Вы должны учитывать случай «Нет, пока нет данных» при кодировании этих реактивные вычисления. Например, if(someCollection.findOne()) удостоверится, что есть хотя бы один документ в someCollection.
В вашем случае это может быть не очень полезно, так как Spacebars отлично справляется с курсорами.