2012-04-12 201 views
61

我一直在试验流星,遇到了一些我无法弄清楚的东西。为了好玩,我试图制作一台老虎机。我有以下的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> 

我想为每个插槽有不同的数字。是否有可能将变量传递给模板?事情是这样的:

<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> 

也许我想这个错误的方式,有一个更好的办法。

+1

**流星已经改变并引入Spacebars **详情请参阅:https://www.discovermeteor.com/blog/spacebars-secrets-exploring-meteor-new-templating-engine/和Dascalescu回答:http ://stackoverflow.com/a/25090098/220060 – nalply 2014-08-02 13:26:53

回答

87

以前所有的答案都是矫枉过正或过时。这里是你如何能的静态参数传递到模板,直接从HTML + Spacebars代码,如流星0.8.4的:

<div class="slot-wrapper"> 
    {{> slot number="1"}} 
    {{> slot number="2"}} 
    ... 
</div> 

<template name="slot"> 
    <div class="number"><span>{{number}}</span></div> 
</template> 

所有您需要做的是通过在{{> template}}纳入呼叫key="value"参数:

{{> slot number="1"}} 

Spacebars Secrets: Exploring Meteor Templates了解更多。


如果你想给调用者模板的数据传递给孩子/套/被叫模板,这里是如何做到这一点:通过什么。相反,从嵌套模板,访问父数据上下文,../

<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> 
+1

谢谢你的答案。任何想法如何从代码中获得这个传递的参数?里面的JavaScript – Kostanos 2015-07-18 15:18:23

+4

@Kostanos - 使用Template.currentData()。 – Rogach 2015-08-13 10:59:52

+0

还有一种方法可以传递模板而不是变量吗?例如... {{>插槽号码= {{>其他模板}}}} ...? – henk 2016-06-08 14:48:16

3

这就是我为实现它所做的。我是相当新的流星所以有可能是一个更好的办法:

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:

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

希望这是给你一些帮助!

+1

有趣的方法。完成工作,但我希望有一个更优雅的方式来做到这一点。 – 2012-04-12 21:52:41

+2

@ dan-dascalescu在底部的答案是最新的做法。它也是最简洁的。 – JohnAllen 2014-08-01 23:30:00

14

原来有另一种方法。

我试图找出如何做到这一点通过搜索各种搜索,发现这个问题,但没有什么符合我的目的。除非要将嵌套模板放在父模板的不同位置,否则TomUnite的答案将有效。

因此,经过多次搜索,我在流星代码库中找到了'一个'答案。 (不是说这是明确的答案,但它的工作)

<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> 

正如你看到的,我们可以按任意顺序指定模板实例。第二个参数是实际应当被定义,所以一个变量:

Template.slots.one = { 
    number: 1 
} 
Template.slots.two = { 
    number: 2 
} 
Template.slots.three = { 
    number: 3 
} 

这可以被制成更简洁代码有一个环形或也许使用underscore.js功能_.extend上的插槽对象。另外,我们可以将多个数据字段传递给这些对象。

+6

这个答案是两岁,不再正确。请考虑删除它 - 你会保持点! – 2014-11-03 00:24:37

+1

@DanDascalescu,现在4岁:P – cenk 2016-06-26 17:08:05

9

我想留下它作为评论,因为它只是对Joc答案的澄清,但不能,所以在这里加上我与之合作的例子。

只有一个参数可以被传递到模板:

{{> singleItemInfo arg1}} 

该参数必须是一个对象,例如:

{ 
    number: 1, 
    number2: 2, 
    numberComposite: { 
     subnum1: 10, 
     subnum2: 20 
    } 
}; 

参数值可以通过他们的密钥来访问,并且在该范围可以切换以获得子项目

{{#with numberComposite}}

下面是该示例的完整代码:

< 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文件>

Template.itemsView.arg1 = { 
    number: 1, 
    number2: 2, 
    numberComposite: { 
     subnum1: 10, 
     subnum2: 20 
    } 
}; 

OUTPUT:

arg1 = 1 arg2 = 2 subArg1 = 10 subArg2 = 20 
+2

作为补充,您可以在那里使用反应性数据源,例如'Template。itemsView.arg1 = function(){Session.get('arg1object')}',子模板将自动更新数据源。 – 2013-07-22 22:16:11

+0

@EmmanuelJoubaud我将数据从助手传递到这样的模板中,这应该是一个被动数据源,但是当助手更新时,数据传递给的模板不会更新。有任何想法吗? – 2017-07-30 13:33:24

+0

从Template.instance()中找出它,我从帮助器中获取模板中的数据(所以我可以进一步操作它)。 ,然后将其返回到模板。我改变它来从Template.instance()。数据获取数据,现在可以工作。 – 2017-07-30 13:46:08

2

我通常使用这两个把手助手:

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

你可以使用它像这样(假设你有一个名为menuItem模板):

{{partial 'menuItem' command='Open'}} 

或迭代内(假设你有一个模板称为userProfile):

{{#each regularUsers}} 
    {{partialWithContext 'userProfile' . isAdmin=false}} 
{{/each}} 

{{#each admins}} 
    {{partialWithContext 'userProfile' . isAdmin=true}} 
{{/each}} 

使用Spacebars,您可以实现某种类似的行为。 在partial.js

Template.partialWithContext.chooseTemplate = function (name) { 
    return Template[name]; 
}; 

partial.html

<template name="partialWithContext"> 
    {{#with chooseTemplate name}} 
     {{#with ../data}} 
      {{> ..}} 
     {{/with}} 
    {{/with}} 
</template> 

使用方法如下:

{{#each commands}} 
    {{> partialWithContext name="commandListItem" data=this isAdmin=false}} 
{{/each}} 
{{#each adminCommands}} 
    {{> partialWithContext name="adminCommandListItem" data=this isAdmin=true}} 
{{/each}} 

希望它会做的伎俩。

+0

这很好用 - 谢谢! – Tomba 2014-02-20 09:03:22

+1

这不再适用于Spacebars的引入。我仍然试图找出解决方案。 – Seiyria 2014-07-19 17:17:42

+1

嗨Seiyria。是的,您不能使用原始解决方案,因为他们不再使用Handlebars。你可以在答案中找到我更新的方法。 – Zsolt 2014-07-22 07:23:36

5

更好的答案:

两个解决方案,可用于制作新的Blaze布局下一个模板上下文敏感的是:

1)传输参数,以利用在能够理解上下文中的模板的辅助模板直接

{{> contextSensitiveTemplate context_1='x' context_2='y' }} 

2)。当你通过一个只有一个参数

{{ contextHelperName ../.. .. this }} 

而且

Template.contextSensitiveTemplate.contextHelperName = function(parent_template, current_template, current_value_inside_each_loop) { 
    return context_dependent_value_or_html  
} 
1

使用this:调用这样的帮手。

<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> 

不需要JavaScript来做到这一点。如果你需要比争论更多的话,请尝试丹的方式。

0

很多很好的信息在这里。我的具体情况是我也想通过一些模板数据。

我想让孩子的Blaze组件重新使用,所以所有的数据都必须传入。举个例子,假设这个组件显示了一个等级(即A,B,C等)。在一个页面上,我想要使用这个组件两次:你的成绩和你的同学的平均成绩。

这里的子组件...

Grade.html

<template name="Grade"> 
    <h3>{{title}}</h3> 
    <div>{{grade}}</h3> 
</template> 

标题可以在父类中硬编码,但档次来自分贝。 以下是我的代码父...

GradePage.html

<template name="GradePage"> 
    {{> Grade grade=gradeYours title="Your Grade" }} 
    {{> Grade grade=gradeClass title="Class Grade" }} 
</template> 

GradePage.js(在现实生活中是被动的,但在这里简化)

Template.GradePage.helpers({ 
    gradeYours: function() { 
     return 'A-'; 
    }, 
    gradeClass: function() { 
     return 'B+'; 
    } 
}); 

就是这样。孩子的组成部分根本不需要伸手去拿它的价值。