Как использовать findOne в шаблоне onCreated и получить к нему доступ в помощнике

Вот мой шаблон onCreated и вспомогательная функция. Я предоставил встроенные комментарии, чтобы внести некоторую ясность. Я вижу, что self.post в конечном итоге установлен, потому что он отображается на моей консоли, когда я регистрирую Template.instance(). Однако, когда я регистрирую Template.instance().post, он всегда не определен.

Template.default.onCreated(function() {
    var self = this;
    self.autorun(function() {
        var postId = FlowRouter.getParam('post_id');
        self.subscribe('onePost', postId);
        self.post = Posts.findOne(FlowRouter.getParam('post_id'));
    });
});
Template.default.helpers({
    poststage: function(stage) {
        console.log(Template.instance()); // I can see post object here
        console.log(Template.instance().post; //always undefined
        if(Template.instance().post) {
            // never true
            return Template.instance().post.stage == stage;
        }
    }
});
Template.default.events({
    'submit form':function(event, instance) {
        Meteor.call('someFunc', instance.post.anotherField);
    }
});

Изменить: я должен добавить, что я стараюсь не писать запрос дважды, потому что я также использую его в событиях шаблона. (см. код).


person drew schmaltz    schedule 21.11.2016    source источник
comment
Реактиввар может помочь, на реактивном метеоре   -  person hafiz ali    schedule 21.11.2016
comment
findOne реактивен по умолчанию.   -  person drew schmaltz    schedule 21.11.2016


Ответы (1)


Это похоже на проблему со временем. Вы подписываетесь на публикацию onePost, но не ждете, пока эта подписка станет .ready(), прежде чем назначать self.post. autorun также кажется излишним. Вам не нужно повторно запускать этот блок кода в блоке onCreated. Я предлагаю:

Template.default.onCreated(function() {
  this.postId = FlowRouter.getParam('post_id');
  self.subscription = subscribe('onePost', this.postId);
});
Template.default.helpers({
  poststage: function(stage) {
    if ( this.subscription.ready()  ){
      return Posts.findOne(this.postId).stage;
    }
  }
});
person Michel Floyd    schedule 21.11.2016
comment
Хорошо, да, я обычно делал бы это так, но я повторно использую запрос позже в коде (в событиях). На самом деле я думал переформулировать вопрос, чтобы отразить это (что я и сделаю сейчас). Ответ может быть просто написать Posts.findOne... снова. Но я подумал, зачем запрашивать дважды? - person drew schmaltz; 21.11.2016
comment
Запросы minimongo относительно дешевы, часто дешевле, чем кодировать себя в углах, пытаясь оптимизировать их. Вы также можете запросить контекст данных в содержащем шаблоне, и тогда у вас будет результат запроса в this - person Michel Floyd; 21.11.2016
comment
Хорошо, я собираюсь просто запросить дважды. Я оставлю этот вопрос открытым и, возможно, немного переформулирую его, чтобы попытаться указать, как написать один запрос и использовать его в шаблоне onCreated, помощниках и событиях. Больше всего расстраивает то, что мой пост доступен в console.log(Template.instance()); но не в Template.instance().post. Я знаю, что он становится доступным, но он должен регистрироваться, когда он становится доступным... ну да ладно... - person drew schmaltz; 21.11.2016
comment
Я подозреваю, что сначала он есть в структуре, но если вы углубитесь в него, вы увидите, что он не определен, и только позже он становится определенным. - person Michel Floyd; 21.11.2016
comment
Он определяется как объект, содержащий документ, но я ОЧЕНЬ УВЕРЕН, что вы правы насчет времени... Я просто подумал, что if(Template.instance().post) { внутри помощника в основном будет делать то же самое как будто ( this.subscription.ready() ) { в вашем примере. Опять же, я убежден, что это также вопрос времени. - person drew schmaltz; 21.11.2016