如何在Handlebars模板中查看所有可用变量

时间:2013-11-05 22:47:13

标签: javascript debugging ember.js handlebars.js

我正在开发我的第一个Ember.js应用程序,并且在连接所有点时遇到了一些麻烦。如果我能看到给定把手模板中的所有可用变量,那将非常有用。

有一个相关问题,但您必须知道范围内的变量才能使用它: How do I add console.log() JavaScript logic inside of a Handlebars template?

如何输出 所有 变量?

7 个答案:

答案 0 :(得分:9)

一个好的选择是使用Handlebars助手在模板中调试'this'的值: 1。

{{#each}}
    {{log this}}    
{{/each}}

,或者 2.类似于@watson建议

{{#each}}
    {{debugger}}
{{/each}}

然后在开发工具

中钻取“this”的本地范围变量

enter image description here

或者,3。您可以直接从Controller init方法中记录内容,例如:

App.UsersController = Ember.ArrayController.extend({
    init: function() {
        console.log(this);
        console.log(this.getProperties('.'));
    }
});

答案 1 :(得分:7)

确保你试用Firebug - 你会对事物有不同的看法,我觉得这很有帮助。但是不要完全放弃镀铬;在某些时候你需要Ember Inspector

我正在使用same debugging helper everyone recommends,这就是Chrome显示的方式:

Chrome inspector isn't very helpful

当我在firebug中展开相同的对象时,我得到以下信息,包括我正在寻找的变量(sources [])以及我在Chrome中没有看到的其他一些有用的属性。

Firefox has more for me to work with

答案 2 :(得分:1)

如果确实需要在模板中转储变量,可以浏览模板AST并输出相关节点的内容(参见编译器sources)。这不是一件容易的事,因为你必须通过试验和错误找到自己的方法,并且代码水平相当低,而且没有太多的评论。

似乎Handlerbars没有您要求的快捷方式,所以步骤如下:

  1. 预编译模板(参见command line source,我认为该函数名为handlebars.precompile()
  2. 探索AST

答案 3 :(得分:1)

您提到的示例Ember应用程序在its app.js中定义了它的EmberObjects。所以基本上,对象上可用的是在那里定义的属性。 (例如subreddittitle等。

如果您想要一种全局可用的方法将对象的属性模式转储到控制台,那么一种方法是创建一个“调试”帮助程序,它可以遍历传入的上下文的成员并将其写出。类似的东西:

Handlebars.registerHelper('debug', function (emberObject) {
    if (emberObject && emberObject.contexts) {
        var out = '';

        for (var context in emberObject.contexts) {
            for (var prop in context) {
                out += prop + ": " + context[prop] + "\n"
            }
        }

        if (console && console.log) {
            console.log("Debug\n----------------\n" + out);
        }
    }
});

然后在你要检查的任何东西上调用它:

<div>Some markup</div>{{debug}}<div>Blah</div>

这将使用EmberObject在范围内的任何内容,因此如果要检查列表元素,则将其弹出{{#each}},而不是具有该列表的对象。

答案 4 :(得分:0)

模板中可用的变量仅受用于渲染模板的模型的约束。

您应该在应用中设置一个断点,在该应用中渲染模板并查看模型中的内容,这将是您可以放入模板的内容。

答案 5 :(得分:0)

几年前,我创建了Barhandles。它将使用Handlebars解析器生成AST,然后从中提取变量引用。 extractSchema方法将(很好)提取模式。该架构不是基于JSON架构或Joi或其他任何东西。这是一种本地格式,可以捕获您可能从Handlebars模板中提取的大部分内容。

因此,此barhandlers.extractSchema('{{foo.bar}}')产生:

{
  "foo": {
    "_type": "object",
    "_optional": false,
    "bar": {
      "_type": "any",
      "_optional": false
    }
  }
}  

要考虑到{{#if expr}}会自动将嵌套引用设为可选。它可以根据{{#with expr}}构造正确地处理范围更改,并且还允许您添加对自己的自定义指令的支持。

我们用它对传递到模板中的数据结构进行了验证,并且为此目的,它运行得很好。

答案 6 :(得分:0)

您可以通过利用Handlebars.parseWithoutProcessing来完成此操作,该方法采用输入模板字符串。如果使用TypeScript,则返回特定类型hbs.AST.Program。您可以只过滤胡子语句,然后遍历这些语句以获取变量名。

此方法还支持Handlebars帮助器,因此您可以获取此键,但是由于这个原因,此功能有点复杂,因为您需要检查mustache语句的不同属性:

/**
 * Getting the variables from the Handlebars template.
 * Supports helpers too.
 * @param input
 */
const getHandlebarsVariables = (input = '') => {
  const ast = Handlebars.parseWithoutProcessing(input);
  return ast.body
    .filter(({ type }) => type === 'MustacheStatement')
    .map((statement) => statement.params[0]?.original || statement.path?.original);
};

这里是TypeScript版本,由于条件属性而涉及到一些内容,但可以帮助您进一步解释类型:

/**
 * Getting the variables from the Handlebars template.
 * Supports helpers too.
 * @param input
 */
const getHandlebarsVariables = (input: string): string[] => {
  const ast: hbs.AST.Program = Handlebars.parseWithoutProcessing(input);

  return ast.body.filter(({ type }: hbs.AST.Statement) => (
    type === 'MustacheStatement'
  ))
  .map((statement: hbs.AST.Statement) => {
    const moustacheStatement: hbs.AST.MustacheStatement = statement as hbs.AST.MustacheStatement;
    const paramsExpressionList = moustacheStatement.params as hbs.AST.PathExpression[];
    const pathExpression = moustacheStatement.path as hbs.AST.PathExpression;

    return paramsExpressionList[0]?.original || pathExpression.original;
  });
};

我制作了一个Codepen来说明这一点。本质上,给出以下模板:

Hello, {{first_name}}! The lottery prize is {{formatCurrency prize_amount}}! Good luck!

它将使用window.prompt向用户询问其姓名和奖金金额。该示例还实现了一个辅助程序formatCurrency。您可以在这里看到它:https://codepen.io/tinacious/pen/GRqYWJE

enter image description here