Помощники шаблона Meteor: {{keyname}} отображается пустым

comment.html:

<template name="comment">
    <img src="{{photo}}"> //blank
    {{photo}} //blank
</template>

comments.js:

Template.comment.helpers({
    photo: function(){
        Meteor.call('getPhoto', function(error, result) {console.log(result);return result})
    }
});

server.js:

Meteor.methods({
    getPhoto: function () {
        return Meteor.user().services.vk.photo;
        }
});

Проблема: console.log возвращает правильное значение, но {{photo}} пусто. Вопрос: почему «фото» пусто?


person bartezr    schedule 07.04.2015    source источник


Ответы (1)


[Обновить]

Я только что понял, в чем проблема.

Meteor.call вызывает асинхронную функцию, например вызов ajax. Итак, Meteor.call('getPhoto') вернет undefined, результат можно получить только в обратном вызове

Meteor.call('getPhoto',function(err,result){console.log(result)});

Имея это в виду, вам нужно будет придумать способ, который фиксирует этот результат в обратном вызове. Одно из решений - использовать ReactiveVariable:

Сначала вам нужно $ meteor add reactive-var

Template.comment.created = function (){
    var $this = this;
    $this.photo = new ReactiveVar("loading");
    Meteor.call('getPhoto', function (err, result) {
        if (err) console.log(err);
        $this.photo.set(result);
    });
}

А теперь определите своего помощника, чтобы получить значение;

   //this is optional
   Template.comment.helpers({
        photo: function(){ 
           return Template.instance().photo.get();
        }
    });

Другое решение - использовать Session:

  //everything here is in the client
  Meteor.call('getPhoto', function(error, result){
    Session.set('thePhoto', result);
  });

  // use reactive Session variable in helper
  Template.comment.helpers({
    photo: function(){
      return Session.get('thePhoto');
    }
  });

Суть использования Session заключается в том, что вы устанавливаете глобальную переменную, и если у вас много комментариев, и каждый комментарий должен иметь уникальную фотографию, Session, вероятно, не лучший способ сделать это.


Вы вызываете функцию Meteor.call, когда объявляете помощников.

Template.comment.helpers({
    photo: Meteor.call('getPhoto', function(error, result) {console.log(result);return result})

});

Итак, то, что вы делаете, равноценно:

var a = Meteor.call('getPhoto', function(error, result) {console.log(result);return result})
Template.comment.helpers({
        photo: a //a is just a value 
});

Для правильной работы .helpers вам следует вместо этого назначить функцию photo.

Template.comment.helpers({
    photo: function(){
       var r;
       Meteor.call('getPhoto', function(error, result) {r = result});
       return r;
    } 
});

Под капотом каждый помощник запускает новый Tracker.autorun. Когда его реактивные зависимости изменяются, помощник запускается повторно. Помощники зависят от их контекста данных, переданных аргументов и других реактивных источников данных, к которым осуществляется доступ во время выполнения. -Из Meteor Doc

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


Если вы все еще не понимаете, что я имею в виду, вот упрощенный пример:

var a = function(){ console.log("hey"); return 1}

var b = a();

var c = a; 

b(); //this would run into an error saying that b is a not a function

c(); //this would console.log "hey"
person Archy Will He 何魏奇    schedule 07.04.2015
comment
Спасибо за ответ. Я изменил файл comment.js, но ничего не изменилось; ( - person bartezr; 07.04.2015
comment
@bartezr он зарегистрировал какой-либо результат? Возможно ли, что это связано с отсутствием " в вашем <template name="comment>? - person Archy Will He 何魏奇; 07.04.2015
comment
@bartezr Я только что понял проблему; дай мне минутку; - person Archy Will He 何魏奇; 07.04.2015
comment
@bartezr только что обновил мой пост; проверено; это определенно сработает сейчас. - person Archy Will He 何魏奇; 07.04.2015
comment
Теперь это хорошо. Спасибо за помощь и извините за потраченное время. - person bartezr; 07.04.2015
comment
@bartezr Не беспокойтесь. Для меня это тоже хорошая версия Meteor Method :) - person Archy Will He 何魏奇; 07.04.2015