Помощник ручек для сравнения значений (если v1 === v2) и Render Upper-Level Scope?

59
8

Для фактического вызова мне нужно что-то вроде этого:

<script id="messagesTemplate" type="text/x-handlebars-template"> 

{{#each messages.messages}}
{{#each to}}
{{#ifCond username messages.sessionUserName}}
<h1>{{username}} is equal to {{messages.sessionUserName}}</h1>
{{else}}
<h1>{{username}} is not equal to {{messages.sessionUserName}}</h1>
{{/ifCond}}
{{/each}}
{{/each}}

Где, в db, 'to' представляет собой массив документов, каждый из которых имеет "имя пользователя".. для этого необходимо === message.sessionUserName, чтобы затем шаблон/рендеринг HTML для определенных значений (например, {{#if read. отмечено}})

"to" : [
{
"user" : ObjectId("53aada6f8b10eb0000ec8a90"),
"username" : "username1",
"updated" : ISODate("2014-07-01T19:39:45Z"),
"_id" : ObjectId("53b30e81b0eff5cb1e2ecb21"),
"read" : {
"marked" : true
}
}
]

Стоит отметить, что и usernameTest & sessionUserName являются значениями, добавленными в конец res.json() через express, поэтому они доступны через messages.usernameTest & messages.sessionUserName, но они отсутствуют в каждом документе. Эти значения являются только доступный в глобальном родительском документе.

res.json({
messages : messages,
sessionUserName: req.session.username,
usernameTest: usernameTest
});

Этот фактор может быть причиной того, почему каждый из этих только рендерингов is equal to, но на самом деле не имеет смысла для третьего (сегмент пути../ссылается на область родительского шаблона):

{{#each messages.messages}}
<h1>{{usernameTest}} is equal to {{sessionUserName}}</h1>
<h1>{{../usernameTest}} is equal to {{../sessionUserName}}</h1>
<h1>{{../messages.usernameTest}} is equal to {{../messages.sessionUserName}}</h1>

Рисование из qaru.site/questions/18027/... для специального помощника сравнения, шаблон, следующий за {{#ifCond v1 v2}}, кажется, не отображает элементы верхнего уровня.

Handlebars.registerHelper('ifCond', function(v1, v2, options) {
if(v1 === v2) {
return options.fn(this);
}
return options.inverse(this);
});

Сравнение ifCond работает вне блока {{#each}}:

<script id="messagesTemplate" type="text/x-handlebars-template"> 

{{#ifCond messages.usernameTest messages.sessionUserName}}
<h1>{{messages.usernameTest}} is equal to {{messages.sessionUserName}}</h1>
{{else}}
<h1>{{messages.usernameTest}} is not equal to {{messages.sessionUserName}}</h1>
{{/ifCond}}

{{#each messages.messages}}
..

.. что делает:

username1 равно username1

Однако он не работает внутри блока {{#each}}:

{{#each messages.messages}}
{{#ifCond messages.usernameTest messages.sessionUserName}}
<h1>{{messages.usernameTest}} is equal to {{messages.sessionUserName}}</h1>
{{else}}
<h1>{{messages.usernameTest}} is not equal to {{messages.sessionUserName}}</h1>
{{/ifCond}}
...

.. только он делает:

равно

Даже с {{../element}}

{{#each messages.messages}}
{{#ifCond messages.usernameTest messages.sessionUserName}}
<h1>{{../messages.usernameTest}} is equal to {{../messages.sessionUserName}}</h1>
{{else}}
<h1>{{../messages.usernameTest}} is not equal to {{../messages.sessionUserName}}</h1>
{{/ifCond}}
...

... рендеринг:

равно

спросил(а) 2014-07-02T08:46:00+04:00 6 лет, 4 месяца назад
1
Решение
74

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

так что вот нормальная ручка

    Handlebars.registerHelper('each', function(context, options) {
var ret = "";

for(var i=0, j=context.length; i<j; i++) {
ret = ret + options.fn(context[i]);
}

return ret;
});

все, что я делаю, устанавливается "this" в свойство с именем root и передает его обратно с результатом. Чтобы преодолеть вложенные циклы, я проверяю существование моего свойства "root", и если он существует, я передаю его по другому мудному root = this.

  Handlebars.registerHelper("myEach", function(context, options) {
var ret = "";

for (var i = 0, j = context.length; i < j; i++) {
if (this.root) {
root = this.root;
} else {
root = this;
}
ret = ret + options.fn(_.extend({}, context[i], {
root: root
}));
}

return ret;
});

Теперь независимо от того, насколько я глубоко в своих циклах, если я хочу использовать что-то из корня, я просто использую root.property.

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

EDIT: Хорошо, так что через 5 минут после публикации этого я прочитал о путях на другом языке шаблонов, а затем понял, что у рулей также есть пути. поэтому вам не нужно делать выше, вы можете просто использовать относительный вложенный путь в своем шаблоне, как показано ниже. Я продолжу использовать помощника, хотя, как я думаю, более аккуратно идти root.property, а не добавлять n много "../" для того, насколько вы вложены.

здесь приведен пример работы с использованием путей

<script type="text/x-handlebars-template" id="messages-template">
Logged in user {{userSession}}
{{#each messages}}
<ul>
<li> Title: {{title}}</li>
<li> Conetent: {{content}}</li>
<li> TO:
<ul>
{{#each to}}

<li>{{user}} {{#ifvalue user ../../userSession}}
thats me
{{else}}
thats not me
{{/ifvalue}}</li>
{{/each}}
</ul>
</li>
</ul>

{{/each}}

</script>

ответил(а) 2014-07-04T17:04:00+04:00 6 лет, 4 месяца назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема