Можно ли использовать функцию в Handlebars #if?

У меня есть объект контроллера, например:

MyApp.objController = Ember.ArrayController.create({
  init: function(data) {
    data.isValid = function() {
      return (data.validity === "valid");
    }
    this.pushObject(MyApp.MyObj.create(data));
  }
});

Мой взгляд похож:

{{#each MyApp.objController}}
  {{#if isValid}}
   <some markup>
   {{else}}
   <some other markup>
  {{/if}}
{{/each}}

Я предполагал, что условие if в Handlebars принимает значения и функции, но это, похоже, не так. Возможно ли это, и я просто делаю это неправильно?

Ответ 1

Если вы определяете свой isValid как property, вы можете использовать его в своем выражении if без создания специального помощника Handlebars, см. http://jsfiddle.net/pangratz666/Dq6ZY/:

Рули

<script type="text/x-handlebars" data-template-name="obj-template" >
    {{view Ember.TextField valueBinding="age" }}
    {{#if isValid}}
        Si Si.
    {{else}}
        Nope!
    {{/if}}
</script>​

JavaScript

App.MyObj = Ember.Object.extend({
    isValid: function() {
        return this.get('age') >= 18;
    }.property('age')
});

Ember.View.create({
    templateName: 'obj-template',
    controller: App.MyObj.create({
        age: 21
    })
}).append();

Ответ 2

Ручки, если утверждения сравниваются только в том случае, если существует значение, если оно является ложным значением (т.е. несуществующим, 0, пустой строкой и т.д.). Вы должны написать пользовательскую вспомогательную функцию.

Вы можете сделать это вот так:

Handlebars.registerHelper('isValid', function (value, options) {
    if (value == "valid") {
        return options.fn(this);
    }
    return options.inverse(this);
});

Это регистрирует вспомогательный блок. Если значение, которое вы передаете, оценивается как "действительное", оно возвращает шаблон, следующий за помощником, с текущими данными. Если он не оценивает значение valid, он возвращает шаблон, следующий за инструкцией else с текущими данными.

Затем в вашем шаблоне вы можете использовать его так:

{{#each MyApp.objController}}
    {{#isValid validity}}
        <some markup>
    {{else}}
        <some other markup>
    {{/isValid}}
{{/each}}

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

Вы также можете настроить общую функцию для обработки этого и других случаев. См. Мой ответ в Логический оператор в handlebars.js {{#if}} условный для примера для общего, если (похоже на приведенный выше ответ)

Ответ 3

Для этого вы можете создать специальный помощник Handlebars.

Ответ 4

Попробуйте следующее:

<ul>
  {{#each subsites}}
      {{#if this}}
        <li>{{{WhatIsTheSiteFor this}}}</li>
      {{else}}  
        <li>no found</li>
      {{/if}}
  {{/each}}
</ul>

здесь вспомогательная функция для WhatIsTheSiteFor:

            Handlebars.registerHelper('WhatIsTheSiteFor', function(sitename) {
          var subsitename = '',
            sitenamestr = '';
            $.each(sitename, function(i, item){
                    sitenamestr += item;
                    return sitenamestr;
            });
          if(sitenamestr==='s.gbin1.com'){
            subsitename = '<a href="#" onclick="location.href='http://'+ sitenamestr +''; return false;">GB搜索引擎</a>';
          }else if(sitenamestr==='m.gbin1.com'){
            subsitename = '<a href="#" onclick="location.href='http://'+ sitenamestr +''; return false;">GB手机阅读</a>';
          }else if(sitenamestr==='rss.gbin1.com'){
            subsitename = '<a href="#" onclick="location.href='http://'+ sitenamestr +''; return false;">RSS消息订阅</a>';
          }
          return subsitename;
        });

Вот демо: http://www.gbin1.com/gb/networks/uploads/71bb1c1e-0cd3-4990-a177-35ce2612ce81/demo6.html