我一直在调试KnockoutJS模板中的问题 .
假设我想绑定到名为“ items " but in the template I make a typo and bind to the (non existing) property " item ”的属性 .
items
item
使用Chrome调试器只会告诉我:
“item”未定义 .
是否有工具,技术或编码样式可以帮助我获得有关绑定问题的更多信息?
当某个范围内的数据存在问题时,我常常做的一件事是用以下内容替换模板/部分:
<div data-bind="text: ko.toJSON($data)"></div>
或者,如果您想要更易读的版本:
<pre data-bind="text: JSON.stringify(ko.toJS($data), null, 2)"></pre>
这将吐出在该范围内绑定的数据,并确保您正确地嵌套事物 .
Update: as of KO 2.1 ,您可以将其简化为:
<pre data-bind="text: ko.toJSON($data, null, 2)"></pre>
现在参数传递给 JSON.stringify .
JSON.stringify
对于本指南,我们将使用official KnockoutJS examples之一 .
假设您想查看第二个联系人(Sensei Miyagi)背后的数据 .
右键单击第二个联系人的第一个输入框(文本为'Sensei'的那个) .
选择'Inspect element' . Chrome开发者工具栏将会打开 .
打开JavaScript控制台窗口 . 您可以通过点击Chrome开发者工具栏左下角的 >= 图标,或打开Chrome开发者工具栏中的"Console"标签,或按Ctrl Shift J来访问控制台
>=
输入以下命令并按Enter键: ko.dataFor($0)
ko.dataFor($0)
您现在应该看到绑定到第二行的数据 . 您可以通过按对象左侧的小三角形来展开数据以导航对象树 .
输入以下命令并按Enter键: ko.contextFor($0)
ko.contextFor($0)
您现在应该看到一个包含整个Knockout上下文的复杂对象,包括root和所有父项 . 当您编写复杂的绑定表达式并且想要尝试不同的构造时,这非常有用 .
这个技巧是Chrome's $0-$4 feature和KnockoutJS's utility methods的组合 . 简而言之,Chrome会记住您在Chrome开发者工具栏中选择了哪些元素,并在别名 $0 , $1 , $2 , $3 , $4 下公开这些元素 . 因此,当您右键单击浏览器中的某个元素并选择'Inspect element'时,此元素将自动在别名 $0 下可用 . 您可以将此技巧与KnockoutJS,AngularJS,jQuery或任何其他JavaScript框架一起使用 .
$0
$1
$2
$3
$4
另一方面是KnockoutJS的实用方法ko.dataFor和ko.contextFor:
ko.dataFor(element) - 返回可用于绑定元素的数据
ko.dataFor(element)
ko.contextFor(element) - 返回DOM元素可用的整个绑定上下文 .
ko.contextFor(element)
请记住,Chrome的JavaScript控制台是一个功能齐全的JavaScript运行时环境 . 这意味着您不仅限于查看变量 . 您可以存储 ko.contextFor 的输出并直接从控制台操作viewmodel . 试试 var root = ko.contextFor($0).$root; root.addContact(); ,看看会发生什么:-)
ko.contextFor
var root = ko.contextFor($0).$root; root.addContact();
快乐的调试!
如果您正在使用Chrome进行开发,那么有一个名为Knockoutjs context debugger的非常棒的扩展(我不隶属于它),可直接在开发人员工具的“元素”面板中显示绑定上下文 .
我找到了另一个可以帮助的人 . 我正在调试一些绑定并尝试使用Ryans示例 . 我收到一个JSON发现循环循环的错误 .
<ul class="list list-fix" data-bind="foreach: detailsView().tabs"> <li> <pre data-bind="text: JSON.stringify(ko.toJS($parent), null, 2)"></pre> <a href="#" data-bind="click: $parent.setActiveTab, text: title"></a> </li> </ul>
但是,使用此方法,将data-bind值替换为以下内容:
<ul class="list list-fix" data-bind="foreach: detailsView().tabs"> <li> <pre data-bind="text: 'click me', click: function() {debugger}"></pre> <a href="#" data-bind="click: $parent.setActiveTab, text: title"></a> </li> </ul>
现在,如果我在打开chrome调试窗口的同时单击PRE元素,我会得到一个填充良好的范围变量窗口 .
找到一个更好的方法:
<pre data-bind="text: ko.computed(function() { debugger; })"></pre>
看看我用的 really simple :
function echo(whatever) { debugger; return whatever; }
要么
function echo(whatever) { console.log(whatever); return whatever; }
然后在html中说,你有:
<div data-bind="text: value"></div>
只需更换它
<div data-bind="text: echo(value)"></div>
More advanced:
function echo(vars, member) { console.log(vars); debugger; return vars[0][member]; } <div data-bind="text: echo([$data, $root, $parents, $parentContext], 'value')"></div>
请享用 :)
UPDATE
另一个烦人的事情是当你试图绑定到一个未定义的值 . 想象一下,在上面的例子中,数据对象只是{}而不是{value:'some text'} . 在这种情况下,你将遇到麻烦,但通过以下调整,你会没事的:
<div data-bind="text: $data['value']"></div>
The easiest way 查看传递给绑定的数据是将数据丢弃到控制台:
<div data-bind="text: console.log($data)"></div>
Knockout将评估文本绑定的值(实际上可以使用任何绑定)并将$ data刷新到控制台浏览器面板 .
我创建了一个名为knockthrough.js的github项目来帮助可视化这些错误 .
https://github.com/JonKragh/knockthrough
它突出显示绑定错误,并在该节点上转储datacontext .
你可以在这里玩一个样本:http://htmlpreview.github.io/?https://github.com/JonKragh/knockthrough/blob/master/default.htm
感谢RP Niemeyer在SO上提供了出色的Knockout代码示例,让我了解到这一点 .
Define a bindingHandler once ,JavaScript库文件中的某个位置 .
ko.bindingHandlers.debug = { init: function(element, valueAccessor) { console.log( 'Knockoutbinding:' ); console.log( element ); console.log( ko.toJS(valueAccessor()) ); } };
而不是简单地使用它喜欢这样:
<ul data-bind="debug: $data">
Advantages
使用Chrome调试器的全部功能,例如“元素面板中的显示”
你不必将自定义元素添加到DOM中,仅用于调试
所有其他答案都会很有效,我只是添加我喜欢做的事情:
在您的视图中(假设您已经绑定了ViewModel):
<div data-bind="debugger: $data"></div>
淘汰赛代码:
ko.bindingHandlers.debugger = { init: function (element, valueAccessor) { debugger; } }
这将暂停调试器中的代码, element 和 valueAccessor() 将包含有 Value 的信息 .
element
valueAccessor()
如果你正在使用Visual Studio和IE开发我喜欢这个 data-bind="somebinding:(function(){debugger; return bindvalue; })()" 我更喜欢echo函数,因为它将使用所有绑定而不是eval文件转到脚本,你可以查看$ context $ data(I也可以在Chrome中使用它;)
data-bind="somebinding:(function(){debugger; return bindvalue; })()"
10 回答
当某个范围内的数据存在问题时,我常常做的一件事是用以下内容替换模板/部分:
或者,如果您想要更易读的版本:
这将吐出在该范围内绑定的数据,并确保您正确地嵌套事物 .
Update: as of KO 2.1 ,您可以将其简化为:
现在参数传递给
JSON.stringify
.分步指南
对于本指南,我们将使用official KnockoutJS examples之一 .
假设您想查看第二个联系人(Sensei Miyagi)背后的数据 .
右键单击第二个联系人的第一个输入框(文本为'Sensei'的那个) .
选择'Inspect element' . Chrome开发者工具栏将会打开 .
打开JavaScript控制台窗口 . 您可以通过点击Chrome开发者工具栏左下角的
>=
图标,或打开Chrome开发者工具栏中的"Console"标签,或按Ctrl Shift J来访问控制台输入以下命令并按Enter键:
ko.dataFor($0)
您现在应该看到绑定到第二行的数据 . 您可以通过按对象左侧的小三角形来展开数据以导航对象树 .
输入以下命令并按Enter键:
ko.contextFor($0)
您现在应该看到一个包含整个Knockout上下文的复杂对象,包括root和所有父项 . 当您编写复杂的绑定表达式并且想要尝试不同的构造时,这非常有用 .
这是什么黑魔法?
这个技巧是Chrome's $0-$4 feature和KnockoutJS's utility methods的组合 . 简而言之,Chrome会记住您在Chrome开发者工具栏中选择了哪些元素,并在别名
$0
,$1
,$2
,$3
,$4
下公开这些元素 . 因此,当您右键单击浏览器中的某个元素并选择'Inspect element'时,此元素将自动在别名$0
下可用 . 您可以将此技巧与KnockoutJS,AngularJS,jQuery或任何其他JavaScript框架一起使用 .另一方面是KnockoutJS的实用方法ko.dataFor和ko.contextFor:
ko.dataFor(element)
- 返回可用于绑定元素的数据ko.contextFor(element)
- 返回DOM元素可用的整个绑定上下文 .请记住,Chrome的JavaScript控制台是一个功能齐全的JavaScript运行时环境 . 这意味着您不仅限于查看变量 . 您可以存储
ko.contextFor
的输出并直接从控制台操作viewmodel . 试试var root = ko.contextFor($0).$root; root.addContact();
,看看会发生什么:-)快乐的调试!
如果您正在使用Chrome进行开发,那么有一个名为Knockoutjs context debugger的非常棒的扩展(我不隶属于它),可直接在开发人员工具的“元素”面板中显示绑定上下文 .
我找到了另一个可以帮助的人 . 我正在调试一些绑定并尝试使用Ryans示例 . 我收到一个JSON发现循环循环的错误 .
但是,使用此方法,将data-bind值替换为以下内容:
现在,如果我在打开chrome调试窗口的同时单击PRE元素,我会得到一个填充良好的范围变量窗口 .
找到一个更好的方法:
看看我用的 really simple :
要么
然后在html中说,你有:
只需更换它
More advanced:
请享用 :)
UPDATE
另一个烦人的事情是当你试图绑定到一个未定义的值 . 想象一下,在上面的例子中,数据对象只是{}而不是{value:'some text'} . 在这种情况下,你将遇到麻烦,但通过以下调整,你会没事的:
The easiest way 查看传递给绑定的数据是将数据丢弃到控制台:
Knockout将评估文本绑定的值(实际上可以使用任何绑定)并将$ data刷新到控制台浏览器面板 .
我创建了一个名为knockthrough.js的github项目来帮助可视化这些错误 .
https://github.com/JonKragh/knockthrough
它突出显示绑定错误,并在该节点上转储datacontext .
你可以在这里玩一个样本:http://htmlpreview.github.io/?https://github.com/JonKragh/knockthrough/blob/master/default.htm
感谢RP Niemeyer在SO上提供了出色的Knockout代码示例,让我了解到这一点 .
Define a bindingHandler once ,JavaScript库文件中的某个位置 .
而不是简单地使用它喜欢这样:
Advantages
使用Chrome调试器的全部功能,例如“元素面板中的显示”
你不必将自定义元素添加到DOM中,仅用于调试
所有其他答案都会很有效,我只是添加我喜欢做的事情:
在您的视图中(假设您已经绑定了ViewModel):
淘汰赛代码:
这将暂停调试器中的代码,
element
和valueAccessor()
将包含有 Value 的信息 .如果你正在使用Visual Studio和IE开发我喜欢这个
data-bind="somebinding:(function(){debugger; return bindvalue; })()"
我更喜欢echo函数,因为它将使用所有绑定而不是eval文件转到脚本,你可以查看$ context $ data(I也可以在Chrome中使用它;)