【问题标题】:Meteor: Access Template Helper (or variable) from another helperMeteor:从另一个助手访问模板助手(或变量)
【发布时间】:2015-03-28 12:16:41
【问题描述】:

如何引用另一个模板助手?比如……

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

【问题讨论】:

    标签: meteor meteor-blaze spacebars meteor-helper


    【解决方案1】:

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

    另外有一种方法可以定义响应式模板实例 变量?

    您可以使用Session variablesReactive variable

    【讨论】:

    • 我认为管理大量的 Session 变量不会太明智 - 也许本地集合会更好。话虽如此,我认为您的答案是一个不错的选择。应该想到的:)
    【解决方案2】:

    您可以,但只能使用 global template helpers

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

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

    【讨论】:

    • 我认为你是对的...我可以将reusableHelper 作为参数传递给子模板...换句话说{{each ...}} {{&gt;XXX percentage=reusableHelper}} {{/each}} - 并在子模板中引用参数。谢谢
    • 感谢您的回答!
    【解决方案3】:

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

    有时很容易陷入“流星方式”,忘记标准的 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);
    });
    

    您可以像这样在 any 模板中使用它:

    {{numeral someNumberVariable format='0,0'}}
    

    【讨论】:

    • UI.registerHelper 现在是 Template.registerHelper
    • 创建Helpers = {...} 的方法对我不起作用,但Template.registerHelper( nameStr, function ) 工作正常。
    【解决方案4】:

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

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

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

    【讨论】:

      【解决方案5】:

      除了 Nils 的回答之外,我还可以使用以下代码访问事件中的模板级别帮助程序:

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

      【讨论】:

        【解决方案6】:

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

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

        【讨论】:

          【解决方案7】:

          我有类似的东西——我在同一个模板中有 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);
              },
          
          });
          

          【讨论】:

            【解决方案8】:

            这只是在工作中再次出现,这次我们使用了模块。在这种情况下,我们有许多大型相关函数,它们必须跨调用维护数据。我希望它们在模板文件之外,但不会完全污染 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。

            【讨论】:

              猜你喜欢
              • 2016-06-10
              • 2013-06-18
              • 2014-09-26
              • 2016-03-04
              • 2015-01-29
              • 1970-01-01
              • 2014-12-12
              • 1970-01-01
              • 2019-04-07
              相关资源
              最近更新 更多