web-dev-qa-db-ja.com

Meteor:別のヘルパーからテンプレートヘルパー(または変数)にアクセスする

別のテンプレートヘルパーからテンプレートヘルパーを参照するにはどうすればよいですか?例えば...

Template.XXX.helpers({
    reusableHelper: function() {
        return this.field1 * 25 / 100; //or some other result
    },
    anotherHelper: function() {
        if (this.reusableHelper() > 300) //this does not work
            return this.reusableHelper() + ' is greater than 300'; 
        else
            return this.reusableHelper() + ' is smaller than 300';
    }
});

また、Template.instance().__ helpers.reusableHelperを試してみました-すべて運がありません。

あるいは、リアクティブなテンプレートインスタンス変数を定義する方法はありますか?

XXXは、同じページに複数回レンダリングするサブテンプレートです。

22
Habib

これは、一般的なコードの使用と同様に、再利用可能なコードを含む別のjavascript関数を作成し、必要な場所から呼び出すことができます。

あなたのコードのように-

function calcField(field){
   return field * 25 / 100
}

そしてあなたのテンプレートヘルパー

Template.XXX.helpers({
    reusableHelper: function() {
        return calcField(this.field1); 
    },
    anotherHelper: function() {
        if (calcField(this.field1) > 300) 
            return calcField(this.field1) + ' is greater than 300'; 
        else
            return calcField(this.field1) + ' is smaller than 300';
    }
});

そして

あるいは、リアクティブなテンプレートインスタンス変数を定義する方法はありますか?

セッション変数 または 反応変数 を使用できます

12
ajduke

グローバルテンプレートヘルパー でのみ可能です。

Blaze._globalHelpers.nameOfHelper()

Iron:Router's pathFor グローバルヘルパーを呼び出す例を次に示します。

Template.ionItem.helpers({
  url: function () {
    var hash = {};
    hash.route = path;
    hash.query = this.query;
    hash.hash = this.hash;
    hash.data = this.data;
    var options = new Spacebars.kw(hash);

    if (this.url){
      return Blaze._globalHelpers.urlFor(options)
    } else if( this.path || this.route ) {
      return Blaze._globalHelpers.pathFor(options)
    }
  }
});

編集:2番目の質問に。ページで何度でも同じテンプレートを呼び出して、異なるデータ属性をそのテンプレートに直接渡すことができますおよび/またはuse #eachデータを反復処理するテンプレートラッパーをブロックします。 #eachは、テンプレートを何度も呼び出して、毎回異なるデータコンテキストを与えます。

#eachの例

<template name="listOfPosts">
  <ul>
    {{#each posts}}
      {{>postListItem}} <!--this template will get a different data context each time-->
    {{/each}}
  </ul>
</template>

属性の例

<template name="postDetails">
  {{>postHeader title="Hello World" headerType="main" data=someHelper}}
  {{>postHeader title="I am a sub" headerType="sub" data=newHelper}}
  {{>postBody doc=bodyHelper}}
</template>
13
benstr

免責事項:これはあなたの質問に直接答えないかもしれませんが、同様のユースケースにこだわっている人々には役立つかもしれません:

標準のJavascriptルールが忘れられている「流星の道」に簡単に縛られることがあります。

あなたがやろうとしていることに似ているように聞こえる2つのユースケース:

1。クライアント側のどこからでもアクセスできるヘルパー/イベントについては、単にグローバルヘルパーを設定します。

たとえば、これをclient/helpers.js

Helpers = {
    someFunction: function(params) {
        /* Do something here */
    }
}

Helpers.someFunction()がallテンプレートで利用可能になりました。

何らかの理由でローカルテンプレートインスタンスをバインドしたい場合、これも標準のJSです。

var boundFunction = Helpers.someFunction.bind(this);

2。テンプレートの再利用可能なBlazeヘルパーinsideを作成するには、Template.registerHelperを使用します

たとえば、この関数は「数値」ライブラリを使用して数値をフォーマットします。

Template.registerHelper('numeral', function(context, opt) {
    var format = (opt.hash && opt.hash.format) || '0,0.00';
    return numeral(context || 0).format(format);
});

これは、anyテンプレートで次のように使用できます。

{{numeral someNumberVariable format='0,0'}}
5
Lee Benson

コレクションフックでより良いソリューションを見つけました。

Item =  new Mongo.Collection('Items');
Item.helpers({
    isAuthor: function(){
        return this.authorId == Meteor.userId();
    },
    color: function(){
        if(this.isAuthor())
            return 'green';
        else
            return 'red';
    }
});

その後、ヘルパーとテンプレートの両方で使用可能なthisの関数になります。

3
Almaju

同じようなものがありました-同じテンプレートに2つのヘルパーがあり、同じ機能にアクセスする必要がありました。ただし、その関数は1)テンプレートのリアクティブvarにアクセスする必要があり、2)はフィルター関数なので、そのリアクティブvarのデータを渡すことはできませんでした。

最終的にテンプレートonCreated()でフィルター関数を定義し、それをリアクティブvarに保存したため、ヘルパーがアクセスできました。

Template.Foo.onCreated(function () {

    this.fooData = new ReactiveVar();

    function filterFoo(key) {
        var foo = Template.instance().fooData.get();
        // filter result is based on the key and the foo data
        return [true|false];
    }

    this.filterFoo = new ReactiveVar(filterFoo);

});

Template.Foo.helpers({
    helper1: function() {
        var filterFn = Template.instance().filterFoo.get();
        return CollectionA.getKeys().filter(filterFn);
    },
    helper2: function() {
        var filterFn = Template.instance().filterFoo.get();
        return CollectionB.getKeys().filter(filterFn);
    },

});
2
zim

これは職場で再び登場し、今回はモジュールを使用しました。この場合、コール間でデータを維持する必要のあるいくつかの大規模で関連する関数がありました。テンプレートファイルの外側に配置したかったのですが、Meteorスコープを完全に汚染したわけではありませんでした。したがって、モジュールを作成し(Meteorスコープ1xを汚染)、テンプレートからその中の関数を呼び出しました。

lib/FooHelpers.js:

FooHelpers = (function () {
    var _foo;

    function setupFoo(value) {
        _foo = value;
    }

    function getFoo() {
        return _foo;
    }

    function incFoo() {
        _foo++;
    }

    return {
        setupFoo: setupFoo,
        getFoo: getFoo,
        incFoo: incFoo
    }
})();

FooTemplate.js:

Template.FooTemplate.helpers({
    testFoo: function() {
        FooHelpers.setupFoo(7);
        console.log(FooHelpers.getFoo());
        FooHelpers.incFoo();
        console.log(FooHelpers.getFoo());
    }
});

コンソール出力は7、8です。

0
zim

Nilsの答えに加えて、次のコードを使用してイベントのテンプレートレベルのヘルパーにアクセスできました。

'click a#back': (event, instance) ->
    if instance.view.template.__helpers[' complete']() && instance.view.template.__helpers[' changed']()
        event.preventDefault()
0
Elias Thompson

この答えは現在不足しているので-アップデートを追加したかった

現在の流星バージョンでは、以下を呼び出すことができるはずです:

var TEMPLATE_NAME = //the name of your template...
var HELPER_NAME = //the name of your helper...
Template[TEMPLATE_NAME].__helpers[' '+HELPER_NAME]

ヘルパーがthisにアクセスできることを確認したい場合は、次のように呼び出す必要があります。

var context = this;
Template[TEMPLATE_NAME].__helpers[' '+HELPER_NAME].call(context,/* args */);

ただし、注意してください-これは将来のMeteorバージョンで壊れる可能性があります。

0
Nils Ziehn