Есть ли способ передать переменные в шаблоны в 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. Если вам нужно больше, чем аргумент, попробуйте Дэн.

Ответ 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+';
    }
});

что он. дочерний компонент не должен вообще достигать своих значений.