流星:从另一个助手访问模板助手(或变量)
Meteor: Access Template Helper (or variable) from another helper
如何引用另一个模板助手?例如...
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 是在同一页面上呈现多次的子模板。
这就像使用通用代码一样,您可以制作另一个 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';
}
});
和
Alternatively is there a way to define reactive Template instance
variables?
你可以使用Session variables or Reactive variable
您可以,但只能使用 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)
}
}
});
编辑:关于你的第二个问题。您可以在页面上多次调用相同的模板,并将不同的数据属性直接传递给它 and/or 使用 #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>
免责声明:这可能无法直接回答您的问题,但可能对遇到类似用例的人有所帮助:
有时很容易陷入 "Meteor way",忘记了标准 Javascript 规则。
两个与您尝试做的事情相似的用例:
1.对于helpers/events客户端任何地方都可以访问的,只需设置一个全局助手即可。
把这个放进去,比方说,client/helpers.js
:
Helpers = {
someFunction: function(params) {
/* Do something here */
}
}
现在 Helpers.someFunction() 可用于 所有 模板。
如果你出于某种原因想要将本地模板实例绑定到它,同样,它是标准的 JS:
var boundFunction = Helpers.someFunction.bind(this);
2。要在模板 内部 创建可重复使用的 Blaze 助手,请使用 Template.registerHelper
例如,此函数使用 "numeral" 库来格式化数字:
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'}}
由于目前缺少此答案 - 我想添加一个更新
在当前的流星版本中,您应该可以调用:
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 版本中中断。
添加到 Nils 的回答中,我已经能够使用以下代码在事件中访问模板级助手:
'click a#back': (event, instance) ->
if instance.view.template.__helpers[' complete']() && instance.view.template.__helpers[' changed']()
event.preventDefault()
我找到了一个更好的收集钩子解决方案:
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 然后成为 this
的函数,可用于助手和模板。
我有类似的东西 -- 我在同一个模板中有 2 个助手需要访问相同的功能。但是,该函数 1) 需要访问模板中的反应变量,2) 是一个过滤函数,所以我不能只传入该反应变量的数据。
我最终在模板 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);
},
});
工作中又遇到这个问题,这次我们用到了模块。在这种情况下,我们有许多必须跨调用维护数据的大型相关函数。我希望它们在模板文件之外,但又不会完全污染 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。
如何引用另一个模板助手?例如...
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 是在同一页面上呈现多次的子模板。
这就像使用通用代码一样,您可以制作另一个 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';
}
});
和
Alternatively is there a way to define reactive Template instance variables?
你可以使用Session variables or Reactive variable
您可以,但只能使用 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)
}
}
});
编辑:关于你的第二个问题。您可以在页面上多次调用相同的模板,并将不同的数据属性直接传递给它 and/or 使用 #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>
免责声明:这可能无法直接回答您的问题,但可能对遇到类似用例的人有所帮助:
有时很容易陷入 "Meteor way",忘记了标准 Javascript 规则。
两个与您尝试做的事情相似的用例:
1.对于helpers/events客户端任何地方都可以访问的,只需设置一个全局助手即可。
把这个放进去,比方说,client/helpers.js
:
Helpers = {
someFunction: function(params) {
/* Do something here */
}
}
现在 Helpers.someFunction() 可用于 所有 模板。
如果你出于某种原因想要将本地模板实例绑定到它,同样,它是标准的 JS:
var boundFunction = Helpers.someFunction.bind(this);
2。要在模板 内部 创建可重复使用的 Blaze 助手,请使用 Template.registerHelper
例如,此函数使用 "numeral" 库来格式化数字:
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'}}
由于目前缺少此答案 - 我想添加一个更新
在当前的流星版本中,您应该可以调用:
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 版本中中断。
添加到 Nils 的回答中,我已经能够使用以下代码在事件中访问模板级助手:
'click a#back': (event, instance) ->
if instance.view.template.__helpers[' complete']() && instance.view.template.__helpers[' changed']()
event.preventDefault()
我找到了一个更好的收集钩子解决方案:
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 然后成为 this
的函数,可用于助手和模板。
我有类似的东西 -- 我在同一个模板中有 2 个助手需要访问相同的功能。但是,该函数 1) 需要访问模板中的反应变量,2) 是一个过滤函数,所以我不能只传入该反应变量的数据。
我最终在模板 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);
},
});
工作中又遇到这个问题,这次我们用到了模块。在这种情况下,我们有许多必须跨调用维护数据的大型相关函数。我希望它们在模板文件之外,但又不会完全污染 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。