在knockoutjs中你可以输出一个漂亮的json格式的ViewModel进行调试
<pre data-bind="text: ko.toJSON($data, null, 2)"></pre>
如果有办法在Aurelia完成同样的事情
答案 0 :(得分:15)
您可以创建自定义元素。
以下是一个例子:https://gist.run?id=9eea8902521f4523ee2c
<强> app.html 强>
<template>
<require from="./debug"></require>
<input value.bind="firstName">
<input value.bind="lastName">
<debug></debug>
</template>
<强> app.js 强>
export class App {
firstName = 'Donald';
lastName = 'Draper';
}
<强> debug.html 强>
<template>
<pre><code>${json}</code></pre>
</template>
<强> debug.js 强>
export class Debug {
bindingContext = null;
updateJson() {
if (this.bindingContext === null) {
this.json = 'null';
} else if (this.bindingContext === undefined) {
this.json = 'undefined'
} else {
// todo: use a stringify function that can handle circular references.
this.json = JSON.stringify(this.bindingContext, null, 2);
}
}
bind(bindingContext) {
this.bindingContext = bindingContext;
this.updateJson();
this.interval = setInterval(::this.updateJson, 150);
}
unbind() {
this.bindingContext = null;
clearInterval(this.interval);
}
}
<强>结果强>
答案 1 :(得分:3)
我最接近的是定义一个值转换器。所以在json.js
我有
export class JsonValueConverter {
toView(value) {
return JSON.stringify(value, null, "\t");
}
}
然后在我的视图模型中index.js
我有我的数据:
export class IndexViewModel {
data = {
name: "nobody!"
};
}
最后视图index.hml
绑定并使用转换器:
<template>
<require from="../resources/converters/json"></require>
<pre textContent.bind="customElementModel | json"></pre>
</template>
然而,由于模型和HTML之间缺乏实时绑定,我现在很难过,所以这可能无法完全回答你的问题?
答案 2 :(得分:2)
作为Jeremy Danyow答案的补充,您还可以在视图模型的特定属性上使用custom binding behavior,而不是整个视图模型。这样做的好处是您可以控制要查看的元素,因此可以避免循环依赖性的问题(如果您只看到那些知道的元素是非循环的...)
首先定义一个JsonValueConverter(与Phil的答案相同):
export class JsonValueConverter {
toView(value) {
return JSON.stringify(value, null, " ");
}
}
然后是绑定行为。请注意,绑定通过自定义信号通知自身以应对深层模型更新。
import {inject} from "aurelia-dependency-injection";
import {ValueConverter} from "aurelia-binding";
import {BindingSignaler, SignalBindingBehavior} from "aurelia-templating-resources";
@inject(BindingSignaler, SignalBindingBehavior)
export class JsonBindingBehavior {
constructor(signaler, signalBindingBehavior) {
this.signaler = signaler;
this.signalBindingBehavior = signalBindingBehavior;
}
bind(binding, scope) {
// bind the signal behavior (ie. listen on signal 'update-json')
this.signalBindingBehavior.bind(binding, scope, 'update-json');
// rewrite the expression to use the JsonValueConverter.
// pass through any args to the binding behavior to the JsonValueConverter
let sourceExpression = binding.sourceExpression;
// do create the sourceExpression only once
if (sourceExpression.rewritten) {
return;
}
sourceExpression.rewritten = true;
let expression = sourceExpression.expression;
sourceExpression.expression = new ValueConverter(
expression,
'json',
sourceExpression.args,
[expression, ...sourceExpression.args]);
// send signal to ourselves each 150ms to update the binding
this.interval = window.setInterval(() => this.signaler.signal('update-json'), 150);
}
unbind(binding, scope) {
window.clearInterval(this.interval);
this.signalBindingBehavior.unbind(binding, scope);
}
}
您可以将两个类放在同一个文件中,例如json.js
。然后在模板中要求它:
<template>
<require from="./json"></require>
...
<pre>${myData & json}</pre>
</template>
...或将其作为全球资源提供。
以下是一个例子:https://gist.run/?id=bde01135fa85f76202c72c11d3cb183a
您也可以将信号提取到第二个自定义行为,就像Jeremy Danyow在this SO answer中所做的那样。有了这个,你就会这样做:
${myData | json & signal:'tick'}