Есть ли способ передать переменные в шаблоны в 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>

может быть, я думаю об этом неправильно, и есть лучший способ.

9 62

9 ответов:

все предыдущие ответы являются излишними или устаревшими. Вот как вы можете передавать статические параметры в шаблоны, непосредственно из кода 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 Секреты: Изучение Шаблонов Метеоров.


если вы хотите передать данные шаблона вызывающего абонента дочернему / вложенному / вызываемому шаблон, вот как это сделать: ничего не передать. Вместо этого, из вложенного шаблона, доступ к родительскому контексту данных,../:

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

оказывается, есть и другой способ.

Я пытался выяснить, как это сделать, погуглив различные поиски и нашел этот вопрос, но ничего, что соответствовало моей цели. Ответ TomUnite работает, если вы не хотите размещать вложенные шаблоны в разных местах родительского шаблона.

поэтому после долгих поисков я нашел ответ " an " в кодовой базе meteor. (Не говорю, что это окончательный ответ, но он работает)

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

Это может быть сделано в более сжатом коде с циклом или, возможно, с помощью подчеркивания.функция js _.расширьте на объекте слотов. Кроме того, мы можем передать несколько полей данных в эти объекты.

Я хотел оставить это в качестве комментария, потому что это просто разъяснение ответа Джока, но не смог, так что здесь это плюс пример, с которым я работал.

в шаблон можно передать только один аргумент:

{{> singleItemInfo arg1}}

этот аргумент должен быть объектом, таких как :

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

значения аргументов могут быть доступны через их ключи, и область может быть переключена, чтобы получить подэлементы с

{{#with numberComposite}}

вот полный код примера :

<body>
    {{ itemsView }}
</body>

<template name="itemsView">
    {{> singleItemInfo arg1}}
</template>

<template name="singleItemInfo">
    arg1 = {{ number }}
    arg2 = {{ number2 }} 
    {{#with numberComposite}}
        subArg1 = {{ subnum1 }}
        subArg2 = {{ subnum2 }}
    {{/with}}
</template>

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

выход:

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

Лучше Ответь:

два решения, которые доступны для создания шаблона с учетом контекста в новом макете 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     
}

это то, что я сделал, чтобы достичь этого. Я довольно новичок в Meteor, поэтому может быть лучший способ:

слот.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>

слот.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
  });
}

надеюсь, что это была некоторая помощь для вас!

я обычно использую эти два руля помощников:

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

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

надеюсь, что это будет делать уловка.

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

эта информация устарела, передача аргументов подробно описана для Blaze layout engine здесь: https://www.discovermeteor.com/blog/spacebars-secrets-exploring-meteor-new-templating-engine/

много хорошей информации здесь. моя конкретная ситуация заключается в том, что я также хотел передать некоторые данные шаблона.

Я хочу сделать дочерний компонент Blaze повторно используемым,поэтому все данные должны быть переданы. в качестве примера предположим, что этот компонент показывает класс (т. е. A, B, C и т. д.). на странице Я хочу использовать компонент дважды: Ваша оценка и средняя оценка ваших одноклассников.

вот дочерний компонент...

класс.HTML-код

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

название может быть жестко закодирован в родителе, но оценка исходит из БД. вот как я кодирую родителя...

градация.HTML-код

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

градация.js (в реальной жизни это реактивный, но упрощенный здесь)

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

вот именно. дочернему компоненту не нужно вообще обращаться, чтобы получить его значения.