【问题标题】:Conditional rendering of template in HandlebarsHandlebars 中模板的条件渲染
【发布时间】:2017-12-10 18:32:52
【问题描述】:

在 Handlebars 中,当没有提供上下文数据时,默认不呈现任何内容:

例如如果上下文中没有提供 title 变量,title: {{ title }} 将呈现 title:

我想构建一个助手,在提供上下文时正确评估模板,但在没有提供上下文变量时显示实际的胡子模板。

Here is a Plunk that illustrates this idea

我可以使用以下代码有条件地显示渲染或模板:

{{#unless title}}
  {{{{raw-helper}}}}
  <h2>title: {{title}}</h2>
  {{{{/raw-helper}}}}
{{else}}
  <h2>title: {{title}}</h2>
{{/unless}}

但我认为一个更优雅、更可重用的解决方案是创建一个特定的助手。我会这样使用它:

{{#raw-unless body}}
    body: {{body}}
{{/raw-unless}}

如果body字符串不为空/null/未定义,它会渲染:

body: 'this is the body provided in context'

如果没有提供body,它会渲染:

body: {{body}}

到目前为止,我尝试像这样注册助手:

Handlebars.registerHelper('raw-unless', function(data, options) {
if(data) {
return options.fn(this);
}
else {
  var out = '{{#raw-helper}}';// 
  out += options.fn();
  out += '{{/raw-helper}}';// 
return out;
}
});

但它呈现:{{#raw-helper}} body: {{/raw-helper}}


我不熟悉自定义助手创建,任何帮助表示赞赏

【问题讨论】:

    标签: javascript handlebars.js templating


    【解决方案1】:

    我不认为您将能够从您的块助手中获取预编译的模板源。因此,我为您看到了两个选项:将默认值直接传递给您的助手或将字符串键传递给您的助手,以便助手可以格式化默认值。

    第一个选项更通用,因为它允许模板定义默认输出:

    Handlebars.registerHelper('render1', function (value, defaultValue) {
        return value || defaultValue;
    });
    

    您可以通过以下方式在模板中使用它:

    body: {{render1 body '{{body}}'}}
    

    如果您不需要在模板中方便地定义默认文本,那么第二个选项很有吸引力,因为它简洁:

    Handlebars.registerHelper('render2', function (key) {
        return this[key] || '{{' + key + '}}';
    });
    

    它将在您的模板中用作:

    body: {{render2 'body'}}
    

    供您参考,我有forked and updated your plunk


    由 OP 编辑​​

    为了处理对助手的错误使用,我最终对它进行了如下调整:

    Handlebars.registerHelper('render1', function (value, defaultValue) {
      var v = (typeof value ==='string')?value:null;
      var d = (typeof defaultValue === 'string')?defaultValue:'ERROR: undefined model / no default value provided';
      return v || d;
    });
    

    它将处理助手的误用,例如:

    body: {{render1 body}}
    

    body未在上下文中提供且未提供默认值时,或:

    body: {{render1}}
    

    当模型未定义时

    【讨论】:

    • 谢谢!我喜欢选项一,因为模板中定义了默认输出;并且使用这样一个简单的助手绝对比使用像 {{{{raw-helper}}}} 这样的语法更优雅和干燥
    【解决方案2】:

    由于您没有在上下文中发送body,因此它正在拒绝

    {{#raw-unless body}}
        body: {{body}}
    {{/raw-unless}}
    

    所以在else 条件中返回你想要显示的文本。在这种情况下

    Handlebars.registerHelper('raw-unless', function(data, options) {
      if (data) {
        return options.fn(this);
      } else {
        return '{{body}}'
      }
    });
    

    【讨论】:

    • 谢谢,但我不希望模板代码出现在帮助程序代码中(关注点分离)。我认为有一种方法可以从辅助函数访问块辅助函数的内容,但这似乎不是 Handlebars 的工作方式:请参阅github.com/rexm/Handlebars.Net/issues/105 所以它似乎在模板中使用了一个条件,以及 {{ {{raw-helper}}}},正如我最初所做的那样,是要走的路
    猜你喜欢
    • 2013-01-27
    • 2012-09-08
    • 2013-01-22
    • 2016-12-12
    • 2011-11-02
    • 1970-01-01
    • 2016-12-28
    • 2014-07-05
    • 1970-01-01
    相关资源
    最近更新 更多