【问题标题】:How to get handlebars to call get() method on context?如何让车把在上下文中调用 get() 方法?
【发布时间】:2026-02-08 20:20:05
【问题描述】:

我将手把本身与 Ember 对象一起用作上下文。我希望它可以像在 Ember+HTMLBars 中一样工作,它似乎调用 get() 而不是假设 context 是 POJO。

var C = Ember.Object.extend({
  value: Ember.computed(function() { return "hello"; })
});
var template = Handlebars.compile("My ember object: {{value}}");
var str = template(C.create());

assert.equal(str, "My ember object: hello"); // Fails. str == "My ember object: [object Object]"

有没有办法让车把调用 get()?

【问题讨论】:

  • 我在旧的 Ember 源代码中看到了该功能的提及,但我不清楚他们是如何做到的。 github.com/emberjs/ember.js/blob/v1.9.1/packages/…
  • 可以尝试{{get this value}} 之类的东西。但是,如果您想单独使用 ember/handlebars,您可能有兴趣使用 Glimmer
  • 我可以使用 get 助手,但是感觉很乱。 get helper 必须包含在我所有的胡须中。
  • 啊,找到了 nameLookup 的文档。对于其他想要这样做的人,请参阅此处最底部的“编译器 API 示例”:github.com/wycats/handlebars.js/blob/…

标签: ember.js handlebars.js


【解决方案1】:

您可以使用Handlebars Compiler API 添加一个在名称查找期间自动调用的助手。

function MyCompiler() {
  Handlebars.JavaScriptCompiler.apply(this, arguments);
}
MyCompiler.prototype = new Handlebars.JavaScriptCompiler();

MyCompiler.prototype.nameLookup = function(parent, name, type) {
  if (type === 'context') {
    return this.source.functionCall('helpers.get', '', [parent, JSON.stringify(name)])
  } else {
    return Handlebars.JavaScriptCompiler.prototype.nameLookup.call(this, parent, name, type);
  }
}

var env = Handlebars.create();
env.registerHelper('get', function(parent, name) {
  return parent.get(name);
})

env.JavaScriptCompiler = MyCompiler;

现在问题中的原始示例有效。

var C = Ember.Object.extend({
  value: Ember.computed(function() { return "hello"; })
});
var template = env.compile("My ember object: {{value}}");
var str = template(C.create());

assert.equal(str, "My ember object: hello"); // PASS!

此答案基于this jsfiddle

【讨论】: