如何让 Meteor.Call 返回模板的值?

Posted

技术标签:

【中文标题】如何让 Meteor.Call 返回模板的值?【英文标题】:How to get Meteor.Call to return value for template? 【发布时间】:2012-05-27 11:53:32 【问题描述】:

我已经尝试过to understand this post regarding this concept,但是我没有得到它。我有以下简单的设置:

/server/test.js
Meteor.methods( 
  abc: function() 
    var result = ;
    result.foo = "Hello ";
    result.bar = "World!";
    return result;
  
);

/client/myapp.js
var q = Meteor.call('abc');
console.log(q);

这个结构返回到控制台undefined

如果我将myapp.js 文件更改为:

Meteor.call('abc', function(err, data) 
  !err ? console.log(data) : console.log(err);

我在控制台中收到Object

理想情况下,这是我想做的,但它不起作用,在控制台中说明:Cannot read property 'greeting' of undefined

/client/myapp.js
var q = Meteor.call('abc');

Template.hello.greeting = function() 
   return q.foo;

在将数据从服务器对象传递到模板中的任何帮助将不胜感激。我还在学习 javascript 和 Meteor。

谢谢!

【问题讨论】:

【参考方案1】:

来自the Meteor.call documentation:

在客户端,如果你不传递回调并且你不在存根中,调用将返回 undefined,你将无法获取方法的返回值。那是因为客户端没有纤程,所以实际上没有任何方法可以阻止远程执行方法。

所以,你会想要这样做:

Meteor.call('abc', function(err, data) 
  if (err)
    console.log(err);

  Session.set('q', data);
);

Template.hello.greeting = function() 
  return Session.get('q').foo;
;

一旦数据可用,这将响应式更新模板。

【讨论】:

嗨,汤姆,非常感谢您的快速回复!我不得不用 ); 关闭你的 Meteor.call 函数,并在 Template.hello.greeting 函数的末尾附加一个分号以使其最终工作(如果你想编辑你的代码)。再次感谢您的帮助! 嗨,Tom,快速提问 - 如果预计数据不会长期发生变化,有没有办法不必使用会话对象?随着变量数量的增加,否则看起来非常浪费和冗长。谢谢。 您或许可以尝试 Amplify 来访问 localStorage。 对于一个流星初学者来说,对于本质上是动态的模板来说,这似乎很奇怪,人们应该通过会话来洗牌......这真的是最好的方法吗? 这个答案不再正确了吗?我用回调调用我的方法,它总是返回结果undefined。它也没有出错,我已经检查过了。【参考方案2】:

这是因为Npm.require 具有异步行为。这就是您必须为Meteor.call 编写回调的原因。

但有一个解决方案,只需使用install(mrt add npm),您将获得一个名为Meteor.sync(//...) 的函数,您可以同时进行游戏:在Meteor.call() 中进行同步和异步。

参考:http://www.sitepoint.com/create-a-meteor-app-using-npm-module/

【讨论】:

【参考方案3】:

您可以使用reactive variable 获取Meteor 方法的返回值以在模板中使用。查看working demonstration on Meteorpad

【讨论】:

Meteorpad 中的示例对我不起作用。此外,部署示例工作......有点。也就是说,它只工作一次,但对我来说,当基础信息更新时不会调用该方法。 方法本身不是响应式的,但可以从响应式上下文中调用,例如 Template.instance().autorun() 或模板助手。【参考方案4】:

我寻求贫民窟解决方案。但是,它对我有用,这对我来说很重要。下面是我的代码,我认为它在概念上解决了 OP 的问题。

在客户端的main.js中:

Meteor.setInterval(function() 
    confirmLogin();

, 5000); 

这将每五秒运行一次 confirmLogin() 函数。

confirmLogin 函数(在客户端的 main.js 中):

function confirmLogin() 
    Meteor.call('loggedIn', function (error, result) 
        Session.set("loggedIn", result);
    );


loggedIn 方法(在服务器的 main.js 中):

loggedIn: function () 
    var toReturn = false;
    var userDetails = Meteor.user();
    if (typeof userDetails["services"] !== "undefined") 
        if (typeof userDetails["services"]["facebook"] != "undefined") 
            toReturn = true;
        
    

    return toReturn;
,

相关助手:

loggedIn: function () 
    return Session.get("loggedIn");

【讨论】:

以上是关于如何让 Meteor.Call 返回模板的值?的主要内容,如果未能解决你的问题,请参考以下文章

如何使 Meteor 方法同步?

如何让函数返回 2 个单独的值? [复制]

如何将 observable 的值从服务传递到组件以更新模板

如何让 PHPUnit MockObjects 根据参数返回不同的值?

Meteor.call 会影响乐观 UI 吗?

假设: Meteor.call() 是不是首先尝试在客户端环境中运行?