2012-04-12 2 views
61

Я экспериментировал с Метером и столкнулся с чем-то, что я не мог понять. Для удовольствия я пытался создать игровой автомат. У меня был следующий HTML:Есть ли способ передать переменные в шаблоны в Meteor?

<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 answer: http : //stackoverflow.com/a/25090098/220060 – nalply

ответ

87

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

+4

@ Kostanos - используйте Template.currentData(). – Rogach

+0

Есть ли способ передать шаблон вместо переменной? например ... {{> номер слота = {{> другой шаблон}}}} ...? – henk

3

Это то, что я сделал для его достижения. Я довольно новый для 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 
    }); 
} 

Надеется, что это была какой-то помощь вам!

+1

Интересный подход. Выполняет свою работу, хотя я бы хотел, чтобы был более элегантный способ сделать это. –

+2

@ Ответ dan-dascalescu внизу - это современный способ сделать это. Это также самое короткое. – JohnAllen

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

Этот ответ два года, и он больше не подходит. Пожалуйста, подумайте об удалении - вы будете держать баллы! –

+1

@DanDascalescu, теперь 4 года: P – cenk

9

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

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

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

ВЫВОД:

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

В качестве дополнения вы можете использовать там реактивные источники данных с чем-то вроде «Шаблон».itemsView.arg1 = function() {Session.get ('arg1object')} ', подтема будет автоматически обновляться источником данных. –

+0

@ EmmanuelJoubaud Я передал данные из помощника в шаблон, подобный этому, который должен быть реактивным источником данных, но шаблон, переданный данным, не обновляется при обновлении помощника. Есть идеи? –

+0

Понял, я получаю данные от шаблона в моем помощнике (так что я могу манипулировать им дальше) от Template.instance(). , а затем верните его в шаблон. Я изменил его, чтобы получить данные из Template.instance(). Данных, которые теперь работают. –

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

+1

Это больше не работает с введением Spacebars. Я все еще пытаюсь выработать решение. – Seiyria

+1

Привет Seiyria. Да, вы не можете использовать оригинальное решение, потому что они больше не используют Handlebars. Вы можете найти мой обновленный подход в ответе. – Zsolt

0

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

+2

Вы должны написать сводку об изменениях в Blaze, а затем напрямую ответить на вопрос. Тогда вы не получаете вниз. (Я не ответил на ваш ответ.) – nalply

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 был повторно использован, поэтому все данные должны быть переданы. Например, этот компонент показывает класс (т. на странице я хочу использовать компонент дважды: ваш сорт и средний класс одноклассников.

вот ребенок компонент ...

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

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

Смежные вопросы