Есть ли способ передать переменные в шаблоны в Meteor?
Я экспериментировал с Метером и столкнулся с чем-то, чего не мог понять. Для удовольствия я пытался создать игровой автомат. У меня был следующий 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
Все предыдущие ответы переполнены или устарели. Здесь, как вы можете передавать статические параметры в шаблоны, непосредственно из кода HTML + Spacebars, как из Meteor 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>
Все, что вам нужно сделать, это передать параметры key="value"
в вызове включения {{> template}}
:
{{> slot number="1"}}
Узнайте больше в Spacebars Secrets: Изучение шаблонов Метеор.
Если вы хотите передать данные шаблона вызывающего объекта в дочерний/вложенный/вызываемый шаблон, вот как это сделать: ничего не пропускайте. Вместо этого из вложенного шаблона обращайтесь к контексту родительских данных, ../
:
<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
Оказывается, есть другой способ.
Я пытался выяснить, как это сделать, отправляя различные поисковые запросы, и нашел этот вопрос, но ничего, что соответствовало моей цели. Ответ 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 на объекте слотов. Кроме того, мы можем передавать несколько полей данных в эти объекты.
Ответ 3
Я хотел оставить это в качестве комментария, потому что это просто пояснение по Joc-ответу, но не могло, поэтому здесь есть плюс пример, с которым я работал.
В шаблон может быть передан только один аргумент:
{{> singleItemInfo arg1}}
этот аргумент должен быть таким, как:
{
number: 1,
number2: 2,
numberComposite: {
subnum1: 10,
subnum2: 20
}
};
значения аргументов могут быть доступны через их ключи, и область может быть переключена для получения подпунктов с помощью
{{#with numberComposite}}
Здесь полный код для примера:
< html file >
<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 >
Template.itemsView.arg1 = {
number: 1,
number2: 2,
numberComposite: {
subnum1: 10,
subnum2: 20
}
};
ВЫВОД:
arg1 = 1 arg2 = 2 subArg1 = 10 subArg2 = 20
Ответ 4
Лучший ответ:
Два решения, которые доступны для создания контекста шаблона в новом макете 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
}
Ответ 5
Это то, что я сделал для этого. Я новичок в Meteor, поэтому может быть лучший способ:
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
});
}
Надеюсь, вам это помогло!
Ответ 6
Обычно я использую эти два помощника Handlebars:
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}}
Надеюсь, это сработает.
Ответ 7
Используйте 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. Если вам нужно больше, чем аргумент, попробуйте Дэн.
Ответ 8
Эта информация устарела, для аргументов Blaze подробно описаны параметры передачи:
https://www.discovermeteor.com/blog/spacebars-secrets-exploring-meteor-new-templating-engine/
Ответ 9
много хорошей информации здесь. моей конкретной ситуацией я также хотел передать некоторые данные шаблона.
Я хочу, чтобы дочерний компонент Blaze был повторно использован, поэтому все данные должны быть переданы в качестве примера. Скажем, этот компонент показывает оценку (т.е. A, B, C и т.д.). на странице я хочу использовать компонент дважды: ваш сорт и средний класс одноклассников.
здесь дочерний компонент...
Grade.html
<template name="Grade">
<h3>{{title}}</h3>
<div>{{grade}}</h3>
</template>
заголовок может быть жестко закодирован в родительском, но класс исходит из db.
здесь, как я кодирую родителя...
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+';
}
});
что он. дочерний компонент не должен вообще достигать своих значений.