是否可以在 Handlebars.js 中提供条件上下文?

Is it possible to provide conditional context in Handlebars.js?

我有模板

<div class="vehicle">
    <div class="model">{{model}}</div>
    <div class="price">{{price}}</div>
</div>

这对于某些上下文子部分很常见(我无法更改上下文),我们称这些子部分为 carbike,上下文只有其中之一:

contractContext = {
    car?,
    bike?,
    ...
}

无论存在哪个子部分,我都需要使此模板正常工作。我可以去:

{{#if car}}
<div class="vehicle">
    <div class="model">{{car.model}}</div>
    <div class="price">{{car.price}}</div>
</div>
{{else}}
<div class="vehicle">
    <div class="model">{{bike.model}}</div>
    <div class="price">{{bike.price}}</div>
</div>
{{/if}}

但我的真实模板要大得多,所以我不想复制那些模板,而是有条件地使用上下文。我试过:

{{#with car ? car : bike}}
<div class="vehicle">
    <div class="model">{{this.model}}</div>
    <div class="price">{{this.price}}</div>
</div>
{{/with}}

(还有 {{#with car || bike}} 由于更复杂的检查,这对于现实生活中的情况是不够的),但是 with 不能这样工作(sandbox) .有没有什么方法可以有条件地设置上下文,或者我必须在 JS 中处理它?

您要做的是在模板中实现一些逻辑(车辆选择)。然而车把和小胡子是 logicless templates 这就是为什么在模板中做这件事不是很明显的原因。我相信做你想做的事情的正确方法是在 javascript 中处理它(所有逻辑都应该在这里)。 喜欢:

const data = {
  vehicle: car || bike
}

和模板

<div class="vehicle">
  <div class="model">{{vehicle.model}}</div>
  <div class="price">{{vehicle.price}}</div>
</div>

还有一种使用 customHelper 来完成此操作的 hacky 方法。只是为了展示车把的酷炫和可定制性:

模板:

{{#choseContext car bike}}
  <div>{{price}}</div>
  <div>{{model}}</div>
{{/choseContext}}

上下文:

{
  bike: {
    price: 422,
    model: 'foo'
  }
}

帮手:

Handlebars.registerHelper('choseContext', function(v1, v2, options) {
  let context = v1 || v2;
  return options.fn(context);
});