我在调试KnockoutJS模板中的问题时一直遇到麻烦。

假设我想绑定到一个名为“items”的属性,但在模板中我犯了一个错字,并绑定到(不存在的)属性“item”。

使用Chrome调试器只告诉我:

“item”没有定义。

是否有工具、技术或编码风格可以帮助我获得关于绑定问题的更多信息?


当前回答

如果你在Magento项目中使用KnockoutJS,你可以使用Magento的自定义afterRender绑定:

<div afterRender="function (target, viewModel) {
    console.log('Rendered element:', target);
    console.log('Associated view model:', viewModel);
    console.log(this === viewModel);
}"></div> 

其他回答

如果你在Magento项目中使用KnockoutJS,你可以使用Magento的自定义afterRender绑定:

<div afterRender="function (target, viewModel) {
    console.log('Rendered element:', target);
    console.log('Associated view model:', viewModel);
    console.log(this === viewModel);
}"></div> 

查看哪些数据被传递给绑定的最简单方法是将数据拖放到控制台:

<div data-bind="text: console.log($data)"></div>

Knockout将计算文本绑定的值(实际上这里可以使用任何绑定)并将$data刷新到控制台浏览器面板。

我经常做的一件事是,当在某个范围内存在数据可用的问题时,将模板/节替换为如下内容:

<div data-bind="text: ko.toJSON($data)"></div>

或者,如果你想要一个可读性稍强的版本:

<pre data-bind="text: JSON.stringify(ko.toJS($data), null, 2)"></pre>

这将输出在该范围内绑定的数据,并让您确保适当地嵌套了内容。

更新:从KO 2.1开始,你可以将其简化为:

<pre data-bind="text: ko.toJSON($data, null, 2)"></pre>

现在参数被传递给JSON.stringify。

在JavaScript库文件中定义一次bindingHandler。

ko.bindingHandlers.debug = 
{
    init: function(element, valueAccessor) 
    {
        console.log( 'Knockoutbinding:' );
        console.log( element );
        console.log( ko.toJS(valueAccessor()) );
    }
};

而不是像这样简单地使用它:

<ul data-bind="debug: $data">

优势

使用Chrome调试器的全部功能,如元素面板中的显示 您不必向DOM添加自定义元素,只是为了调试

看看我用的一个非常简单的东西:

function echo(whatever) { debugger; return whatever; }

Or

function echo(whatever) { console.log(whatever); return whatever; }

然后在html中,你有:

<div data-bind="text: value"></div>

把它替换成

<div data-bind="text: echo(value)"></div>

更高级的:

function echo(vars, member) { console.log(vars); debugger; return vars[0][member]; }

<div data-bind="text: echo([$data, $root, $parents, $parentContext], 'value')"></div>

享受:)

更新

另一个恼人的事情是当你试图绑定到一个未定义的值。在上面的例子中,假设数据对象只是{}not {value: 'some text'}。在这种情况下,你会遇到麻烦,但通过以下调整,你会没事的:

<div data-bind="text: $data['value']"></div>