2015-04-16 2 views
1

Im пытается создать учебное приложение, где на данный момент ему нужно получить первые 7 сообщений из субредакта, а затем, если он еще не находится в базе данных, добавьте его в базу данных. Однако по какой-то причине он запускает как if, так и еще 7 раз, и я не могу понять, почему. Вот вспомогательный метод:Метеор уникальное поле документа?

Template.posts.helpers({ 
    posts : function() { 
    Meteor.call('getPosts', "tifu", function(e, results){ 
     var result = JSON.parse(results.content).data.children; 
     Session.set('postsResults', result); 
    }); 
    for(var i=0; i<7; i++){ 
     var result = Session.get('postsResults')[i].data; 
     if(Posts.find({r_id: result.id}).count() == 0){ 
     console.log("if"); 
     } else {   
     console.log("else"); 
     }; 
    }; 
    return Posts.find(); 
    } 
}); 

и HTML сторона:

<template name="posts"> 
    <div class="col-md-12 posts-div"> 
     {{#each posts }} 
     <div class="col-md-8"> 
      <div class="panel panel-primary"> 
      <div class="panel-heading"> 
       <h3 class="panel-title">{{ title }}</h3> 
      </div> 
      <div class="panel-body">{{{ body }}}</div> 
      <div class="panel-footer"> 
       <div class="col-md-2">{{ score }}</div> 
       <div class="col-md-2 col-md-offset-3">{{ subreddit }}</div> 
       <div class="col-md-2 col-md-offset-3">{{ createdBy }}</div> 
       <div class="clearfix"></div> 
      </div> 
      </div> 
     </div> 
     <div class="col-md-4"> 
      <div class="panel panel-primary"> 
      </div> 
     </div> 
     {{/each}} 
    </div> 
    <hr> 
</template> 

Я заменил вставки кода с помощью простых журналов консоли и эти результаты я получаю:

if 
if 
if 
if 
if 
if 
if 
else 
else 
else 
else 
else 
else 
else 

Когда я запускаю Posts.find({r_id: result.id}).count() == 0 в консоли, я получаю false с Posts.findOne({r_id: result.id}) == null, но по какой-то причине в javascript-файле он по-прежнему запускает истинную часть, и тогда я получаю как 50 копий t он тот же пост, которого я пытаюсь избежать.

+1

Ну, это потому, что помощники запускают async, поэтому сначала == 0 его истинное, а затем другое утверждение, истинное, то есть то, что вы получаете из других консолей, например, console 'console.log (Posts.find ({r_id: result.id }). count()) 'внутри оператора if, и вы получите' 0' и lester за 1 секунду, вы получите другой номер. – Ethaan

ответ

1

Не рекомендуется использовать Meteor.call в помощнике. Помощник function будет повторно запускаться каждый раз, когда происходит реактивное изменение. Вот почему он работает так много раз.

Используйте Template.onCreated обратного вызова вместо:

Template.posts.onCreated(function() { 
    Meteor.call('getPosts', "tifu", function(e, results){ 
     var result = JSON.parse(results.content).data.children; 
     Session.set('postsResults', result); 
    }); 
}); 

И ваш помощник:

Template.posts.helpers({ 
    posts : function() { 
    var r = Session.get('postsResults') 

    for(var i=0; i<7; i++){ 
     if(!r) continue; 
     var result = r[i].data; 
     if(Posts.find({r_id: result.id}).count() == 0){ 
      console.log("if"); 
     } else {   
      console.log("else"); 
     }; 
     }; 
    return Posts.find(); 
    } 
}); 

Вторая вещь, чтобы иметь в виду, Session.get('postsResults')будет быть null в то время как результат Meteor.call возвращается, для несколько сотен миллисекунд. Если вы сделаете Session.get('postsResults')[i].data, вы получите исключение.

Вот почему я добавил условную проверку, чтобы продолжить цикл, если r - null. Таким образом, вы ждете результата, а postsfunction будет повторно запускать и пересчитывать результаты с новыми данными.