I've been experimenting with Meteor and ran into something I couldn't figure out. For fun, I was trying to make a slot machine. I had the following HTML:
我一直在用流星做实验,却遇到了一些我搞不懂的东西。为了好玩,我试着做一个*。我有以下HTML:
<div class="slot-wrapper">
{{> slot}}
{{> slot}}
{{> slot}}
</div>
<template name="slot">
<div class="slot">
<div class="number"><span>{{ number }}</span></div>
<div class="divider"></div>
</div>
</template>
I want to have a different number for each slot. Is it possible to pass variables into template? Something like this:
我想要每个槽有不同的数字。是否可能将变量传递到模板中?是这样的:
<div class="slot-wrapper">
{{> slot 1}}
{{> slot 2}}
{{> slot 3}}
</div>
<template name="slot">
<div class="slot">
<div class="number"><span>{{ number i}}</span></div>
<div class="divider"></div>
</div>
</template>
Maybe I'm thinking about this the wrong way and there's a better way.
也许我想错了,还有更好的办法。
9 个解决方案
#1
88
All of the previous answers are overkill or outdated. Here's how you can pass static parameters into templates, directly from HTML+Spacebars code, as of Meteor 0.8.x:
之前所有的答案都是多余的或过时的。以下是如何将静态参数直接从HTML+空格键代码传递到模板中,就像流星0.8.x:
<div class="slot-wrapper">
{{> slot number="1"}}
{{> slot number="2"}}
...
</div>
<template name="slot">
<div class="number"><span>{{number}}</span></div>
</template>
All you have to do is pass key="value"
parameters in the {{> template}}
inclusion call:
您所要做的就是在{{>模板}包含调用中传递key="value"参数:
{{> slot number="1"}}
Learn more at Spacebars Secrets: Exploring Meteor Templates.
了解更多关于太空酒吧的秘密:探索流星模板。
If you want to pass the caller template's data to the child/nested/called template, here's how to do it: pass nothing. Instead, from the nested template, access the parent data context, ../
:
如果您想要将调用者模板的数据传递给子/嵌套/称为模板,下面是如何做到这一点:什么都不传递。相反,从嵌套模板中访问父数据上下文../:
<div class="slot-wrapper">
{{> slot number="1"}}
{{> slot number="2"}}
...
</div>
<template name="slot">
<div>Machine name: {{../name}}</div>
<div class="number"><span>{{number}}</span></div>
</template>
#2
14
Turns out there is another way.
事实证明还有另一种方法。
I was trying to find out how to do this by googling various searches and found this question but nothing that suited my purpose. TomUnite's answer works unless you want to put the nested templates in different places in the parent template.
我试图通过谷歌搜索找到这个问题,找到了这个问题,但没有找到适合我的目的。除非您想将嵌套模板放在父模板的不同位置,否则TomUnite的答案是有效的。
So after much searching I found 'an' answer in the meteor codebase. (Not saying it's the definitive answer but it does work)
所以在搜索之后,我在流星代码库中找到了一个答案。(并不是说这是确定的答案,但它确实有效)
<template name="slots">
{{> slot one}}
<div>..something else</div>
{{> slot three}}
{{> slot two}}
</template>
<template name="slot">
<div class="slot">
<div class="number"><span>{{number}}</span></div>
<div class="divider"></div>
</div>
</template>
As you see we can specify the template instances in any order. The second parameter is actually a variable that should be defined, so:
如您所见,我们可以按任何顺序指定模板实例。第二个参数实际上是一个需要定义的变量,所以:
Template.slots.one = {
number: 1
}
Template.slots.two = {
number: 2
}
Template.slots.three = {
number: 3
}
This could be made into more succinct code with a loop or maybe using the underscore.js function _.extend on the slots object. Also, We can pass multiple fields of data into these objects.
可以使用循环或下划线将其编写成更简洁的代码。js函数_。扩展槽对象。此外,我们还可以向这些对象传递多个数据字段。
#3
9
I wanted to leave this as a comment, because it's just a clarification on Joc's answer, but couldn't, so here it is with plus the example I worked with.
我想把这句话留作评论,因为这只是对Joc的回答的一个澄清,但不能,这里是加上我的例子。
Only ONE argument can be passed to the template :
只有一个参数可以传递给模板:
{{> singleItemInfo arg1}}
this argument must be an object such as :
这个参数必须是一个对象,例如:
{
number: 1,
number2: 2,
numberComposite: {
subnum1: 10,
subnum2: 20
}
};
the argument values can be accessed via their keys, and the scope can be switched to get the subitems with the
可以通过它们的键访问参数值,并且可以切换作用域以获取带有
{{#with numberComposite}}
{ { #与numberComposite } }
Here's the full code for the example :
下面是示例的完整代码:
<html file>
< html文件>
<body>
{{ itemsView }}
</body>
<template name="itemsView">
{{> singleItemInfo arg1}}
</template>
<template name="singleItemInfo">
arg1 = {{ number }}
arg2 = {{ number2 }}
{{#with numberComposite}}
subArg1 = {{ subnum1 }}
subArg2 = {{ subnum2 }}
{{/with}}
</template>
<javascript file>
< javascript文件>
Template.itemsView.arg1 = {
number: 1,
number2: 2,
numberComposite: {
subnum1: 10,
subnum2: 20
}
};
OUTPUT:
输出:
arg1 = 1 arg2 = 2 subArg1 = 10 subArg2 = 20
#4
5
Better Answer:
更好的回答:
The two solutions that are available to making a template context sensitive under the new Blaze layout are:
在新的Blaze布局下,可以使用两个解决方案使模板上下文变得敏感:
1) Passing arguments to the template directly
1)直接将参数传递给模板。
{{> contextSensitiveTemplate context_1='x' context_2='y' }}
2) Using a helper in the template that understands the context. Call the helper like this:
在理解上下文的模板中使用助手。这样称呼助手:
{{ contextHelperName ../.. .. this }}
And
和
Template.contextSensitiveTemplate.contextHelperName = function(parent_template, current_template, current_value_inside_each_loop) {
return context_dependent_value_or_html
}
#5
3
This is what I have done to achieve it. I am fairly new to Meteor so there may be a better way:
这就是我为实现这一目标所做的。我对流星还很陌生,所以可能有更好的办法:
Slot.html:
Slot.html:
<head>
<title>Slot</title>
</head>
<body>
<div class="slot-wrapper">
{{> slots}}
</div>
</body>
<template name="slots">
{{#each slots}}
{{> slot}}
{{/each}}
</template>
<template name="slot">
<div class="slot">
<div class="number"><span>{{number}}</span></div>
<div class="divider"></div>
</div>
</template>
Slot.js:
Slot.js:
if (Meteor.is_client) {
Template.slots.slots = function () {
var returnArray = new Array();
returnArray[0] = { 'number': 10 };
returnArray[1] = { 'number': 87 };
returnArray[2] = { 'number': 41 };
return returnArray;
};
}
if (Meteor.is_server) {
Meteor.startup(function () {
// code to run on server at startup
});
}
Hope this was some help to you!
希望这对你有所帮助!
#6
2
I usually use these two Handlebars helpers:
我通常使用这两个把手:
Handlebars.registerHelper('partial', function(templateName, options) {
return new Handlebars.SafeString(Template[templateName](options.hash));
});
Handlebars.registerHelper('partialWithContext', function(templateName, context, options) {
var extendedContext = _.extend(context, options.hash);
return new Handlebars.SafeString(Template[templateName](context));
});
You can use it like this (suppose you have a template called menuItem
):
您可以这样使用它(假设您有一个名为menuItem的模板):
{{partial 'menuItem' command='Open'}}
Or inside an iteration (suppose you have a template called userProfile
):
或者在迭代中(假设您有一个名为userProfile的模板):
{{#each regularUsers}}
{{partialWithContext 'userProfile' . isAdmin=false}}
{{/each}}
{{#each admins}}
{{partialWithContext 'userProfile' . isAdmin=true}}
{{/each}}
With Spacebars, you can achieve a somewhat similar behavior. In partial.js
:
使用空格键,您可以实现类似的行为。在部分。js:
Template.partialWithContext.chooseTemplate = function (name) {
return Template[name];
};
In partial.html
:
在partial.html:
<template name="partialWithContext">
{{#with chooseTemplate name}}
{{#with ../data}}
{{> ..}}
{{/with}}
{{/with}}
</template>
Use it like this:
使用它是这样的:
{{#each commands}}
{{> partialWithContext name="commandListItem" data=this isAdmin=false}}
{{/each}}
{{#each adminCommands}}
{{> partialWithContext name="adminCommandListItem" data=this isAdmin=true}}
{{/each}}
Hope it will do the trick.
希望它能奏效。
#7
1
Use this
when you pass just one argument.
当你只传递一个参数时使用这个。
<div class="slot-wrapper">
{{> slot 1}}
{{> slot 2}}
</div>
<template name="slot">
<div class="slot">
<div class="number"><span>{{this}}</span></div>
<div class="divider"></div>
</div>
</template>
No javascript required to do it. If you need more than a argument try Dan's way.
不需要javascript来完成。如果你需要更多的争论,试试丹的方法。
#8
0
This information is out of date, passing arguments is described in detail for Blaze layout engine here: https://www.discovermeteor.com/blog/spacebars-secrets-exploring-meteor-new-templating-engine/
这个信息已经过时了,传递的参数在这里详细描述了火焰布局引擎:https://www.discovermeteor.com/blog/spacebars-secrets-exploring-meteor-new-templating-engine/。
#9
0
lots of good info in here. my specific situation is i also wanted to pass in some template data.
这里有很多很好的信息。我的具体情况是,我也想传递一些模板数据。
i want to make the child Blaze component re-usable, so all the data must be passed in. as an example, let's say this component shows a grade (i.e. A, B, C, etc.). on a page, i want to use the component twice: your grade, and your classmates' average grade.
我想让child Blaze组件可重用,因此必须传递所有数据。例如,假设这个组件显示一个等级(即a、B、C等)。在一页上,我想用两次分量:你的成绩,你同学的平均成绩。
here's the child component...
这是子组件…
Grade.html
Grade.html
<template name="Grade">
<h3>{{title}}</h3>
<div>{{grade}}</h3>
</template>
title can be hardcoded in the parent, but the grade comes from the db. here's how i code the parent...
标题可以硬编码在父类中,但是分数来自db。下面是我如何为父类编码……
GradePage.html
GradePage.html
<template name="GradePage">
{{> Grade grade=gradeYours title="Your Grade" }}
{{> Grade grade=gradeClass title="Class Grade" }}
</template>
GradePage.js (in real life it's reactive, but simplified here)
GradePage。js(在现实生活中,它是被动的,但在这里简化了)
Template.GradePage.helpers({
gradeYours: function () {
return 'A-';
},
gradeClass: function () {
return 'B+';
}
});
that's it. the child component doesn't have to reach out at all to get its values.
就是这样。子组件不需要伸出来获取它的值。
#1
88
All of the previous answers are overkill or outdated. Here's how you can pass static parameters into templates, directly from HTML+Spacebars code, as of Meteor 0.8.x:
之前所有的答案都是多余的或过时的。以下是如何将静态参数直接从HTML+空格键代码传递到模板中,就像流星0.8.x:
<div class="slot-wrapper">
{{> slot number="1"}}
{{> slot number="2"}}
...
</div>
<template name="slot">
<div class="number"><span>{{number}}</span></div>
</template>
All you have to do is pass key="value"
parameters in the {{> template}}
inclusion call:
您所要做的就是在{{>模板}包含调用中传递key="value"参数:
{{> slot number="1"}}
Learn more at Spacebars Secrets: Exploring Meteor Templates.
了解更多关于太空酒吧的秘密:探索流星模板。
If you want to pass the caller template's data to the child/nested/called template, here's how to do it: pass nothing. Instead, from the nested template, access the parent data context, ../
:
如果您想要将调用者模板的数据传递给子/嵌套/称为模板,下面是如何做到这一点:什么都不传递。相反,从嵌套模板中访问父数据上下文../:
<div class="slot-wrapper">
{{> slot number="1"}}
{{> slot number="2"}}
...
</div>
<template name="slot">
<div>Machine name: {{../name}}</div>
<div class="number"><span>{{number}}</span></div>
</template>
#2
14
Turns out there is another way.
事实证明还有另一种方法。
I was trying to find out how to do this by googling various searches and found this question but nothing that suited my purpose. TomUnite's answer works unless you want to put the nested templates in different places in the parent template.
我试图通过谷歌搜索找到这个问题,找到了这个问题,但没有找到适合我的目的。除非您想将嵌套模板放在父模板的不同位置,否则TomUnite的答案是有效的。
So after much searching I found 'an' answer in the meteor codebase. (Not saying it's the definitive answer but it does work)
所以在搜索之后,我在流星代码库中找到了一个答案。(并不是说这是确定的答案,但它确实有效)
<template name="slots">
{{> slot one}}
<div>..something else</div>
{{> slot three}}
{{> slot two}}
</template>
<template name="slot">
<div class="slot">
<div class="number"><span>{{number}}</span></div>
<div class="divider"></div>
</div>
</template>
As you see we can specify the template instances in any order. The second parameter is actually a variable that should be defined, so:
如您所见,我们可以按任何顺序指定模板实例。第二个参数实际上是一个需要定义的变量,所以:
Template.slots.one = {
number: 1
}
Template.slots.two = {
number: 2
}
Template.slots.three = {
number: 3
}
This could be made into more succinct code with a loop or maybe using the underscore.js function _.extend on the slots object. Also, We can pass multiple fields of data into these objects.
可以使用循环或下划线将其编写成更简洁的代码。js函数_。扩展槽对象。此外,我们还可以向这些对象传递多个数据字段。
#3
9
I wanted to leave this as a comment, because it's just a clarification on Joc's answer, but couldn't, so here it is with plus the example I worked with.
我想把这句话留作评论,因为这只是对Joc的回答的一个澄清,但不能,这里是加上我的例子。
Only ONE argument can be passed to the template :
只有一个参数可以传递给模板:
{{> singleItemInfo arg1}}
this argument must be an object such as :
这个参数必须是一个对象,例如:
{
number: 1,
number2: 2,
numberComposite: {
subnum1: 10,
subnum2: 20
}
};
the argument values can be accessed via their keys, and the scope can be switched to get the subitems with the
可以通过它们的键访问参数值,并且可以切换作用域以获取带有
{{#with numberComposite}}
{ { #与numberComposite } }
Here's the full code for the example :
下面是示例的完整代码:
<html file>
< html文件>
<body>
{{ itemsView }}
</body>
<template name="itemsView">
{{> singleItemInfo arg1}}
</template>
<template name="singleItemInfo">
arg1 = {{ number }}
arg2 = {{ number2 }}
{{#with numberComposite}}
subArg1 = {{ subnum1 }}
subArg2 = {{ subnum2 }}
{{/with}}
</template>
<javascript file>
< javascript文件>
Template.itemsView.arg1 = {
number: 1,
number2: 2,
numberComposite: {
subnum1: 10,
subnum2: 20
}
};
OUTPUT:
输出:
arg1 = 1 arg2 = 2 subArg1 = 10 subArg2 = 20
#4
5
Better Answer:
更好的回答:
The two solutions that are available to making a template context sensitive under the new Blaze layout are:
在新的Blaze布局下,可以使用两个解决方案使模板上下文变得敏感:
1) Passing arguments to the template directly
1)直接将参数传递给模板。
{{> contextSensitiveTemplate context_1='x' context_2='y' }}
2) Using a helper in the template that understands the context. Call the helper like this:
在理解上下文的模板中使用助手。这样称呼助手:
{{ contextHelperName ../.. .. this }}
And
和
Template.contextSensitiveTemplate.contextHelperName = function(parent_template, current_template, current_value_inside_each_loop) {
return context_dependent_value_or_html
}
#5
3
This is what I have done to achieve it. I am fairly new to Meteor so there may be a better way:
这就是我为实现这一目标所做的。我对流星还很陌生,所以可能有更好的办法:
Slot.html:
Slot.html:
<head>
<title>Slot</title>
</head>
<body>
<div class="slot-wrapper">
{{> slots}}
</div>
</body>
<template name="slots">
{{#each slots}}
{{> slot}}
{{/each}}
</template>
<template name="slot">
<div class="slot">
<div class="number"><span>{{number}}</span></div>
<div class="divider"></div>
</div>
</template>
Slot.js:
Slot.js:
if (Meteor.is_client) {
Template.slots.slots = function () {
var returnArray = new Array();
returnArray[0] = { 'number': 10 };
returnArray[1] = { 'number': 87 };
returnArray[2] = { 'number': 41 };
return returnArray;
};
}
if (Meteor.is_server) {
Meteor.startup(function () {
// code to run on server at startup
});
}
Hope this was some help to you!
希望这对你有所帮助!
#6
2
I usually use these two Handlebars helpers:
我通常使用这两个把手:
Handlebars.registerHelper('partial', function(templateName, options) {
return new Handlebars.SafeString(Template[templateName](options.hash));
});
Handlebars.registerHelper('partialWithContext', function(templateName, context, options) {
var extendedContext = _.extend(context, options.hash);
return new Handlebars.SafeString(Template[templateName](context));
});
You can use it like this (suppose you have a template called menuItem
):
您可以这样使用它(假设您有一个名为menuItem的模板):
{{partial 'menuItem' command='Open'}}
Or inside an iteration (suppose you have a template called userProfile
):
或者在迭代中(假设您有一个名为userProfile的模板):
{{#each regularUsers}}
{{partialWithContext 'userProfile' . isAdmin=false}}
{{/each}}
{{#each admins}}
{{partialWithContext 'userProfile' . isAdmin=true}}
{{/each}}
With Spacebars, you can achieve a somewhat similar behavior. In partial.js
:
使用空格键,您可以实现类似的行为。在部分。js:
Template.partialWithContext.chooseTemplate = function (name) {
return Template[name];
};
In partial.html
:
在partial.html:
<template name="partialWithContext">
{{#with chooseTemplate name}}
{{#with ../data}}
{{> ..}}
{{/with}}
{{/with}}
</template>
Use it like this:
使用它是这样的:
{{#each commands}}
{{> partialWithContext name="commandListItem" data=this isAdmin=false}}
{{/each}}
{{#each adminCommands}}
{{> partialWithContext name="adminCommandListItem" data=this isAdmin=true}}
{{/each}}
Hope it will do the trick.
希望它能奏效。
#7
1
Use this
when you pass just one argument.
当你只传递一个参数时使用这个。
<div class="slot-wrapper">
{{> slot 1}}
{{> slot 2}}
</div>
<template name="slot">
<div class="slot">
<div class="number"><span>{{this}}</span></div>
<div class="divider"></div>
</div>
</template>
No javascript required to do it. If you need more than a argument try Dan's way.
不需要javascript来完成。如果你需要更多的争论,试试丹的方法。
#8
0
This information is out of date, passing arguments is described in detail for Blaze layout engine here: https://www.discovermeteor.com/blog/spacebars-secrets-exploring-meteor-new-templating-engine/
这个信息已经过时了,传递的参数在这里详细描述了火焰布局引擎:https://www.discovermeteor.com/blog/spacebars-secrets-exploring-meteor-new-templating-engine/。
#9
0
lots of good info in here. my specific situation is i also wanted to pass in some template data.
这里有很多很好的信息。我的具体情况是,我也想传递一些模板数据。
i want to make the child Blaze component re-usable, so all the data must be passed in. as an example, let's say this component shows a grade (i.e. A, B, C, etc.). on a page, i want to use the component twice: your grade, and your classmates' average grade.
我想让child Blaze组件可重用,因此必须传递所有数据。例如,假设这个组件显示一个等级(即a、B、C等)。在一页上,我想用两次分量:你的成绩,你同学的平均成绩。
here's the child component...
这是子组件…
Grade.html
Grade.html
<template name="Grade">
<h3>{{title}}</h3>
<div>{{grade}}</h3>
</template>
title can be hardcoded in the parent, but the grade comes from the db. here's how i code the parent...
标题可以硬编码在父类中,但是分数来自db。下面是我如何为父类编码……
GradePage.html
GradePage.html
<template name="GradePage">
{{> Grade grade=gradeYours title="Your Grade" }}
{{> Grade grade=gradeClass title="Class Grade" }}
</template>
GradePage.js (in real life it's reactive, but simplified here)
GradePage。js(在现实生活中,它是被动的,但在这里简化了)
Template.GradePage.helpers({
gradeYours: function () {
return 'A-';
},
gradeClass: function () {
return 'B+';
}
});
that's it. the child component doesn't have to reach out at all to get its values.
就是这样。子组件不需要伸出来获取它的值。