Превратите метод метеора, возвращающий один объект, в контекст для руля.

В базовом примере таблицы лидеров на сайте meteor.com есть метод selected_name.

  Template.leaderboard.selected_name = function () {
    var player = Players.findOne(Session.get("selected_player"));
    return player && player.name;
  };

  {{#if selected_name}}
  <div class="details">
    <div class="name">{{selected_name}}</div>
    <input type="button" class="inc" value="Give 5 points" />
  </div>
  {{/if}}

Вместо этого я хотел бы вернуть весь объект игрока, а затем обработать этот объект как контекст с помощью руля. Хотел бы я сказать так:

  Template.leaderboard.selected_person = function () {
    var player = Players.findOne(Session.get("selected_player"));
    return player || false;
  };

  {{#if selected_person}}
  <div class="details">
    <div class="name">{{name}}</div>
    <input type="button" class="inc" value="Give 5 points" />
  </div>
  {{/if}}

Приведенный выше блок #if на самом деле не работает в метеоре. Оператор #if просто оценивает метод selected_person, а вложенный {{name}} абсолютно ничего не делает. Я хотел бы знать, можно ли написать метод, чтобы возвращаемый объект можно было использовать в качестве контекста блока #if.


person lashleigh    schedule 15.04.2012    source источник


Ответы (2)


Решено! Если я просто использую #with вместо #if, то все работает отлично. Как говорится в документах руля You can shift the context for a section of a template by using the built-in with block helper.

  {{#if selected_person}}
  {{#with selected_person}}
  <div class="details">
    <div class="name">{{name}}</div>
    <input type="button" class="inc" value="Give 5 points" />
  </div>
  {{/with}}
  {{/if}}

Вложенный if/with довольно громоздкий и явно не стоит того, чтобы отображать только имя, но я мог бы вспомнить случаи, когда было бы полезно специальное отображение большего количества атрибутов одного объекта.

person lashleigh    schedule 15.04.2012
comment
Оператор if, похоже, не нужен, выглядит как with on сам по себе, как я и ожидал. - person jonathanKingston; 15.04.2012
comment
@jonathanKingston В случае, когда нет выбранного человека, он отобразит остальные элементы div, что может быть не тем, что вы ищете. В моем случае использования я определенно хочу, чтобы фрагмент отображался только в том случае, если там есть значение. - person Benson; 16.04.2012
comment
В качестве альтернативы, объедините if и with в один помощник. Например: Handlebars.registerHelper('ifwith', function(context, options) { if (context) return options.fn(context); });. Таким образом, selected_person вызывается только один раз, а не один раз из-за if и один раз из-за with. - person Joel Nation; 30.05.2012

Я сделал нечто подобное, но я не думаю, что это «правильный путь»?

Template.leaderboard.selected_person = function () {
    return Players.find(Session.get("selected_player"));
};

{{#each selected_person}}
<div class="details">
    <div class="name">{{name}}</div>
    <input type="button" class="inc" value="Give 5 points" />
</div>
{{/each}}
person Josh Petitt    schedule 15.04.2012
comment
Я тоже делал что-то подобное, пока не нашел ответ Лэшли об использовании #with. Работает как шарм. :-) - person Benson; 16.04.2012