簡體   English   中英

如何在模板助手中使用 Meteor 方法

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM