Meteor: Access Template Helper (or variable) from

2019-01-17 20:54发布

How can I reference a template helper from another one? For example...

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';
    }
});

I have also tried Template.instance().__helpers.reusableHelper - all with no luck.

Alternatively is there a way to define reactive Template instance variables?

XXX is a sub-template that renders multiple times on the same page.

8条回答
Juvenile、少年°
2楼-- · 2019-01-17 20:59

Adding on to Nils' answer, I have been able to access Template level helpers in events using the following code:

'click a#back': (event, instance) ->
    if instance.view.template.__helpers[' complete']() && instance.view.template.__helpers[' changed']()
        event.preventDefault()
查看更多
贼婆χ
3楼-- · 2019-01-17 21:06

i had something similar -- i had 2 helpers in the same template that needed access to the same function. however, that function 1) needed access to a reactive var in the template, and 2) is a filter function, so i couldn't just pass in the data of that reactive var.

i ended up defining the filter function in the templates onCreated() and stored it in a reactive var, so the helpers could access it.

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);
    },

});
查看更多
The star\"
4楼-- · 2019-01-17 21:08

This like using of common code, you can make another javascript function which contains the your reusable code and call it from wherever you required.

Like in your code-

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

and in you template helper-

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';
    }
});

and

Alternatively is there a way to define reactive Template instance variables?

you can use Session variables or Reactive variable

查看更多
家丑人穷心不美
5楼-- · 2019-01-17 21:11

this just came up again at work, and this time we used modules. in this case, we had a number of large, related functions that had to maintain data across calls. i wanted them outside the template file but not totally polluting the Meteor scope. so we made a module (polluting the Meteor scope 1x) and called the functions therein from the template.

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());
    }
});

console output is 7, 8.

查看更多
smile是对你的礼貌
6楼-- · 2019-01-17 21:12

Since this answer is currently missing - I wanted to add an update

In the current meteor version, you should be able to call:

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

You should call it like this, if you want to make sure the helper has access to this:

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

But be careful - this could break in future Meteor versions.

查看更多
Melony?
7楼-- · 2019-01-17 21:19

I found a better solution with collection hooks:

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

I then becomes functions of this, usable in both helpers and templates.

查看更多
登录 后发表回答