22

如何从另一个模板助手引用模板助手?例如...

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 是在同一页面上多次呈现的子模板。

4

8 回答 8

14

您可以但只能使用全局模板助手

Blaze._globalHelpers.nameOfHelper()

这是一个调用Iron:Router 的 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)
    }
  }
});

编辑:关于你的第二个问题。您可以在页面上多次调用相同的模板并将不同的数据属性直接传递给它和/或使用#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>
于 2015-01-29T10:41:37.657 回答
12

这就像使用通用代码一样,您可以创建另一个包含可重用代码的 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';
    }
});

或者有没有办法定义反应模板实例变量?

您可以使用会话变量反应变量

于 2015-01-29T10:19:59.237 回答
5

免责声明:这可能无法直接回答您的问题,但可能对遇到类似用例的人有所帮助:

有时很容易陷入“流星方式”,标准的 Javascript 规则被遗忘。

两个听起来与您尝试做的类似的用例:

1. 对于可以在客户端任何地方访问的助手/事件,只需设置一个全局助手。

把它放进去,比如说client/helpers.js

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

现在 Helpers.someFunction() 可用于所有模板。

如果您出于某种原因想将本地模板实例绑定到它,再次,它是标准 JS:

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

2. 要模板中创建可重用的 Blaze 助手,请使用 Template.registerHelper

例如,此函数使用“数字”库来格式化数字:

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

您可以在任何模板中使用它,如下所示:

{{numeral someNumberVariable format='0,0'}}
于 2015-03-03T17:12:05.810 回答
3

我找到了一个更好的收集钩子解决方案:

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,可用于帮助程序和模板。

于 2015-11-03T22:57:20.440 回答
1

我有类似的东西——我在同一个模板中有 2 个助手需要访问相同的功能。但是,该函数 1) 需要访问模板中的响应式 var,并且 2) 是一个过滤器函数,所以我不能只传入该响应式 var 的数据。

我最终在模板 onCreated() 中定义了过滤器函数,并将其存储在一个反应​​变量中,因此帮助者可以访问它。

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

});
于 2016-05-27T17:22:05.033 回答
0

由于目前缺少此答案-我想添加更新

在当前的流星版本中,您应该可以调用:

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 版本中中断。

于 2015-06-27T17:10:08.723 回答
0

添加到 Nils 的答案中,我已经能够使用以下代码访问事件中的模板级别帮助程序:

'click a#back': (event, instance) ->
    if instance.view.template.__helpers[' complete']() && instance.view.template.__helpers[' changed']()
        event.preventDefault()
于 2015-10-09T19:12:29.547 回答
0

这只是在工作中再次出现,这次我们使用了模块。在这种情况下,我们有许多大型的相关函数,它们必须跨调用维护数据。我希望它们在模板文件之外,但不会完全污染 Meteor 范围。所以我们制作了一个模块(污染 Meteor 范围 1x)并从模板中调用其中的函数。

库/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。

于 2016-06-29T18:54:49.197 回答