15

如果我有两个车把模板想要检查同一个函数的返回值怎么办?有正确的方法吗?显然我可以这样做:

var say_foo = function() {
  alert('foo');
};

Template.foo.say_foo = say_foo;
Template.bar.say_foo = say_foo;

但是有没有办法直接通过 Template 对象来做到这一点?由于这是 JavaScript,我可以将函数分配给任何对象的任何属性,但我尝试这样做:

Template.say_foo = function() { alert('foo'); };

当然模板没有找到这个功能。

只是对最佳实践等感到好奇。谢谢!

4

7 回答 7

17

我认为更好的版本是(如果您使用默认设置的把手):

Template.registerHelper('my_helper', function() {
     // code
});

您可以使用 {{my_helper}} 从任何模板调用它!

希望能帮助到你 :)

于 2012-04-19T20:41:40.587 回答
16

根据 Meteor 文档,正确的方法是使用 UI 命名空间,它将绑定到下面使用的任何模板引擎,而不是直接使用 Handlebars 或空格键。这是文档中的链接。http://docs.meteor.com/#ui_registerhelper

因此,要从 client.js 中使用的任何模板访问通用函数:

UI.registerHelper('stub', function() {
     // code
});

更新:

显然,文档已改回使用

Template.registerHelper('stub', function() {
     // code
});

然后在html文件中使用{{stub}}访问变量。

于 2014-08-24T06:22:27.167 回答
2

这是我想出的解决问题的方法。这是使用 CoffeeScript 完成的。如果您不使用 CoffeeScript,可以在此处将其转换为 JavaScript 。

首先,定义extendTemplate函数:

extendTemplate = (template, mixin) ->
  helpers = ({name, method} for name, method of mixin when name isnt "events")
  template[obj.name] = obj.method for obj in helpers

  if mixin.events?
    template.events?.call(template, mixin.events)

  template

loginMixin然后,声明一个您希望在多个模板之间共享的具有帮助器和事件的对象(我的称为):

loginMixin =
  merge_with_email: ->
    return Session.get 'account_merge__merge_with_email'

  events:
    'click button#merge_login': (event, template) ->

      email = $(template.find('#email')).val()
      password = $(template.find('#password')).val()

      Meteor.loginWithPassword email, password, (error)->
        if error
          console.error "Failed to login."

      return false

然后,在声明你的模板之后,你可以使用上面的 mixin 来扩展它们。使用以下代码,我正在扩展我的registerlogin模板:

extendTemplate Template.register, loginMixin
extendTemplate Template.login, loginMixin

最后,这是我的login.html样子:

<template name="login">
    <div class="alert">
        <a class="close" data-dismiss="alert" href="#">×</a>
        <h4 class="alert-heading">Merge accounts</h4>
        <form id="register_form" class="form-inline" action="#">
            <p class="help-block">Please login with {{merge_with_email}}.</p>
            <label for="email">Email:</label>
            <input id="email" type="text" class="input-medium" />
            <label for="password">Password:</label>
            <input id="password" type="password" class="input-medium" />
            <button class="btn" id="merge_login">Login</button>
        </form>
    </div>
</template>

由于我也扩展了我的register模板,register.html因此也可以使用{{merge_with_email}}并处理按钮的click事件。merge_login

于 2013-03-24T17:28:06.520 回答
2

现在有了 Meteor 1.0,这似乎已经改变了。经过一番挖掘,我发现您现在可以使用以下内容在助手之间重用代码:

https://docs.meteor.com/#/full/template_registerhelper

Template.registerHelper("checkedIf",function(value){
  return (value)? "checked":"";
});

这使它在所有助手中都可用!

于 2014-11-03T11:26:37.337 回答
1

不确定我是否理解您的要求,但我认为您所做的没有任何问题 - 您将函数分配给变量以便多次重用它。

如果想要减少输入或让 20 个不同的模板重用它而不是 2 个,您可以执行以下操作:

var templates = ['foo', 'bar', 'baz', 'barz', 'bliz', blaz'];
for (var i=0; i < templates.length; i++) { 
    Template[templates[i]].say_foo = say_foo;
}

但是 IMO 的可读性较差,并且没有真正需要这样做。

编辑 - 更好的解决方案

刚刚意识到您可能想要这样做的原因 - 确保每个模板都具有该say_foo属性,因此您不必担心每次创建新模板时手动添加它,您可以这样做:

for (var t in Template)
    Template[t].say_foo = say_foo;
于 2012-04-19T04:59:55.087 回答
1

您当前的方法应该有效。一个更短的版本是:

Template.foo.say_foo = 
Template.bar.say_foo = function() { alert('foo'); };
于 2012-04-19T13:23:08.560 回答
0

在弄乱了 Gezim 的出色答案后,我在 Meteor 1.3+ 中意识到你可以简单地运行:

Template.register.helpers(MyMixin.helpers);
Template.register.events(MyMixin.helpers);

但是如果你想要一个 extendTemplate 函数:

// Note: above code is probably simpler.

function extendTemplate(template, mixin) {
  if (mixin.helpers && template.helpers) {
    template.helpers(mixin.helpers);
  }
  if (mixin.events && template.events) {
    template.events(mixin.events);
  }
  return template;
};

extendTemplate(Template.register, {
  events: { ... },
  helpers: { ... },
});
于 2017-01-03T21:10:19.843 回答