如何定义一个也可以在模板助手中调用的Meteor方法?
我有这两个文件:
file:lib / test.js
Meteor.methods({
viewTest : function (str) {
return str;
}
});
file:client / myView.js
Template.helloWorld.helpers({
txt : function () {
var str = Meteor.call('viewTest', 'Hello World.');
return str;
}
});
当我给“str”一个正常的字符串时,一切正常。但在这种情况下,我的模板没有任何价值。我定义 - 测试 - 在同一个文件中,该方法是一个正常的函数,并试图调用该函数。我得到的错误是该函数不存在。所以我认为Meteor会在它知道我为它定义的方法之前尝试渲染模板。但我认为这有点不寻常 - 不是吗?
答案 0 :(得分:57)
现在有一种新的方法(Meteor 0.9.3.1),它不会污染会话命名空间
Template.helloWorld.helpers({
txt: function () {
return Template.instance().myAsyncValue.get();
}
});
Template.helloWorld.created = function (){
var self = this;
self.myAsyncValue = new ReactiveVar("Waiting for response from server...");
Meteor.call('getAsyncValue', function (err, asyncValue) {
if (err)
console.log(err);
else
self.myAsyncValue.set(asyncValue);
});
}
在'创建的'回调,您创建一个ReactiveVariable的新实例(请参阅docs)并将其附加到模板实例。
然后调用您的方法,当回调触发时,将返回的值附加到反应变量。
然后,您可以设置助手以返回反应变量的值(现在附加到模板实例),并在方法返回时重新运行。
但请注意,您必须添加reactive-var软件包才能正常工作
$ meteor add reactive-var
答案 1 :(得分:23)
Sashko添加了一个名为meteor-reactive-method的简洁小包来解决此问题。
$ meteor add simple:reactive-method
Template.helloWorld.helpers({
txt: function() {
return ReactiveMethod.call('viewTest', 'Hello World.');
}
});
正如我在common mistakes中指出的那样,助手应该是无副作用的,所以我谨慎使用这种技巧。但是,对于以下情况,它是一个非常方便的快捷方式:
答案 2 :(得分:12)
您需要将返回值与Session变量接口,因为请求是异步的:
Template.helloWorld.helpers({
txt : function () {
return Session.get("txt") || "Loading";
}
});
Template.helloWorld.created = function() {
Meteor.call('viewTest', 'Hello World.', function(err, result) {
Session.set("txt", result);
});
}
所以.render应该在你的模板加载时调用一次(至少应该使用较新版本的Meteor。)
将调用并显示该值。否则会说“正在加载”。
答案 3 :(得分:11)
客户端上的方法是异步的,它们的返回值始终是未定义的。要获取方法返回的实际值,您需要提供回调:
Meteor.call('method', 'argument', function(error, result) {
....
});
现在,在帮助程序中使用结果并不容易。但是,您可以将其作为数据对象存储在模板中,然后在帮助程序中将其返回:
Template.template.created = function() {
var self = this;
self.data.elephantDep = new Deps.Dependency();
self.data.elephant = '';
Meteor.call('getElephant', 'greenOne', function(error, result) {
self.data.elephant = result;
self.data.elephantDep.changed();
});
};
Template.template.showElephant = function() {
this.elephantDep.depend();
return this.elephant;
};
答案 4 :(得分:2)
这是预期的行为。您没有按预期使用methods
。
您的代码在客户端上使用相同的名称定义服务器方法viewTest
和相应的方法存根。
Meteor.call('viewTest', 'Hello World.');
远程调用服务器上的viewTest
,并行运行客户端上的存根。
关于存根的返回值,请参阅文档here,特别是:
在客户端上,将忽略存根的返回值。存根运行 因为它们的副作用:它们旨在模拟结果 服务器的方法将做什么,但不等待轮次 旅行延误。
关于服务器方法的返回值,请参阅文档here,特别是:
在客户端上,如果你没有通过回调而你不在 存根,调用将返回undefined,你将无法得到 返回方法的值。那是因为客户没有 纤维,所以它实际上没有任何方法可以阻挡遥控器 执行方法。
答案 5 :(得分:0)
@msavin有一个很好的小包装:
https://atmospherejs.com/msavin/fetcher