在Meteor中模板之间共享功能

时间:2012-04-19 01:36:09

标签: meteor

如果我有两个想要检查相同功能的返回值的车把模板怎么办?有没有正确的方法来做到这一点?显然我可以这样做:

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

当然模板找不到这个功能。

对最佳做法等感到好奇。谢谢!

7 个答案:

答案 0 :(得分:17)

我认为会有更好的版本(如果您使用Handlebars,这是默认设置):

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

您可以使用{{my_helper}}!

从任何模板中调用此内容

希望有所帮助:)

答案 1 :(得分:16)

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

<击>

因此,可以从client.js中使用的任何模板访问泛型函数:

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

<击>

更新

显然是docs have changed back to using

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

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

答案 2 :(得分:2)

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

首先,定义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事件。

答案 3 :(得分:2)

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

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

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

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

答案 4 :(得分: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;

答案 5 :(得分:1)

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

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

答案 6 :(得分: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: { ... },
});