Meteor 模板助手:{{keyname}} 显示空白

Meteor Template helpers: {{keyname}} showing blank

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 returns 正确的值,但 {{photo}} 是空的。 问题:为什么'photo'是空的?

[更新]

我刚刚意识到这里有什么问题。

Meteor.call 正在调用一个异步函数,就像 ajax 调用一样。所以 Meteor.call('getPhoto') 将 return 未定义,结果只能在回调

中检索
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;
    } 
});

Under the hood, each helper starts a new Tracker.autorun. When its reactive dependencies change, the helper is rerun. Helpers depend on their data context, passed arguments and other reactive data sources accessed during execution. -From Meteor Doc

.helpers 应该被调用,因为您要使用 .helpers 的真正原因是在您的视图中启用 reactivity。因此 .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"