[英]How to use Meteor methods inside of a template helper
如何定義在模板助手中也可調用的 Meteor 方法?
我有這兩個文件:
文件:lib/test.js
Meteor.methods({
viewTest : function (str) {
return str;
}
});
文件:客戶端/myView.js
Template.helloWorld.helpers({
txt : function () {
var str = Meteor.call('viewTest', 'Hello World.');
return str;
}
});
當我給“str”一個普通字符串時,一切正常。 但在這種情況下,我的模板沒有任何價值。 我在同一個文件中定義 - 為了測試 - 在該方法是一個普通函數的地方,並試圖調用該函數。 我得到的錯誤是該函數不存在。 所以我認為 Meteor 試圖在它知道我為它定義的方法之前渲染模板。 但我認為這有點不尋常——不是嗎?
現在有一種新方法可以做到這一點(Meteor 0.9.3.1),它不會污染 Session 命名空間
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);
});
}
在“created”回調中,您創建一個 ReactiveVariable 的新實例(請參閱文檔)並將其附加到模板實例。
然后你調用你的方法,當回調觸發時,你將返回的值附加到反應變量。
然后你可以設置你的助手來返回反應變量的值(它現在附加到模板實例),它會在方法返回時重新運行。
但請注意,您必須添加reactive-var 包才能使其工作
$ meteor add reactive-var
Sashko添加了一個名為meteor-reactive-method的簡潔小包來解決這個問題。
$ meteor add simple:reactive-method
Template.helloWorld.helpers({
txt: function() {
return ReactiveMethod.call('viewTest', 'Hello World.');
}
});
正如我在常見錯誤中指出的那樣,助手應該沒有副作用,所以我會謹慎使用這種技術。 但是,對於以下情況,這是一個非常方便的快捷方式:
您需要將返回值與 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);
});
}
所以 .rendered 應該在你的模板加載時調用一次(至少它應該與新版本的 Meteor 一起使用。)
該值將被調用並顯示。 否則它會說“正在加載”。
客戶端的方法是異步的,它們的返回值總是未定義的。 要獲取該方法返回的實際值,您需要提供一個回調:
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;
};
這是預期的行為。 您沒有按照預期使用methods
。
您的代碼在客戶端上定義了一個服務器方法viewTest
和一個相應的同名方法存根。
Meteor.call('viewTest', 'Hello World.');
遠程調用服務器上的viewTest
並並行運行客戶端上的存根。
關於存根的返回值,請參見此處的文檔,特別是:
在客戶端,存根的返回值被忽略。 存根是為了它們的副作用而運行的:它們旨在模擬服務器方法將執行的操作的結果,但無需等待往返延遲。
關於服務器方法的返回值請看這里的文檔,特別是:
在客戶端,如果不傳遞回調並且不在存根內部,則調用將返回 undefined,並且您將無法獲取該方法的返回值。 那是因為客戶端沒有纖程,所以實際上沒有任何方法可以阻止方法的遠程執行。
@msavin 有一個很好的小包:
https://atmospherejs.com/msavin/fetcher
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.