我正在开发我的第一个 Ember.js 应用程序,但在连接所有点时遇到了一些麻烦。如果我可以在给定的车把模板中看到所有可用的变量,那将非常有帮助。
有一个相关的问题,但您必须知道使用它的范围内的变量: 如何在 Handlebars 模板中添加 console.log() JavaScript 逻辑?
如何输出所有变量?
我正在开发我的第一个 Ember.js 应用程序,但在连接所有点时遇到了一些麻烦。如果我可以在给定的车把模板中看到所有可用的变量,那将非常有帮助。
有一个相关的问题,但您必须知道使用它的范围内的变量: 如何在 Handlebars 模板中添加 console.log() JavaScript 逻辑?
如何输出所有变量?
一个不错的选择是使用 Handlebars 助手在模板中调试“this”的值:1。
{{#each}}
{{log this}}
{{/each}}
或者,2.类似于@watson 建议
{{#each}}
{{debugger}}
{{/each}}
然后在开发工具中深入了解“this”的本地范围变量
或者,3. 您可以直接从 Controller init 方法中记录内容,例如:
App.UsersController = Ember.ArrayController.extend({
init: function() {
console.log(this);
console.log(this.getProperties('.'));
}
});
确保你尝试了 Firebug——你会对事物有不同的看法,我觉得这很有帮助。但不要完全放弃 chrome;在某些时候你会需要Ember Inspector。
我正在使用每个人都推荐的调试助手,这就是 Chrome 显示它的方式:
当我在 firebug 中展开同一个对象时,我得到以下信息,包括我正在寻找的变量 (sources[]) 以及我在 Chrome 中没有看到的其他一些有用的属性。
几年前我创建了Barhandles 。它将使用 Handlebars 解析器生成 AST,然后从中提取变量引用。该extractSchema
方法将 - 很好 - 提取模式。该架构不是基于 JSON Schema 或 Joi 或任何东西。这是一种本土格式,可以捕获您可能从 Handlebars 模板中提取的大部分内容。
所以,这barhandlers.extractSchema('{{foo.bar}}')
会产生:
{
"foo": {
"_type": "object",
"_optional": false,
"bar": {
"_type": "any",
"_optional": false
}
}
}
它将考虑到 an{{#if expr}}
将自动使嵌套引用成为可选。它可以根据{{#with expr}}
构造正确处理范围更改,并且还允许您添加对自己的自定义指令的支持。
我们用它来验证我们传递给模板的数据结构,它为此目的工作得很好。
The sample Ember app you mention defines its EmberObjects right in its app.js. So basically, what's available on the objects are the properties that are defined onto them there. (e.g. subreddit
has a title
, etc).
If you want a globally available way to dump an object's property schema out to the console, one approach would be to create a "debug" helper that walks the members of the passed-in contexts and writes them out. Something like:
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);
}
}
});
Then call it on whatever you want to inspect:
<div>Some markup</div>{{debug}}<div>Blah</div>
This will use whatever EmberObject is in scope, so pop it inside of an {{#each}}
if you want to inspect the list elements, as opposed to the object with that list.
您可以通过利用Handlebars.parseWithoutProcessing
which 接受输入模板字符串来做到这一点。如果您使用 TypeScript,则返回特定类型hbs.AST.Program
。您可以仅过滤 mustache 语句,然后遍历这些语句以获取变量名称。
此方法还支持 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
用于询问用户的姓名和奖金金额。该示例还实现了一个 helper formatCurrency
。你可以在这里看到它:https ://codepen.io/tinacious/pen/GRqYWJE
模板中可用的变量仅受您用于呈现模板的模型的约束。
您应该在您的应用程序中设置一个断点来渲染模板并查看此时您的模型中的内容,这将您可以放入模板中的内容。