How to debug template binding errors for KnockoutJ

2019-01-15 23:23发布

I keep having trouble with debugging problems in KnockoutJS templates.

Say I want to bind to a property called "items" but in the template I make a typo and bind to the (non existing) property "item".

Using the Chrome debugger only tells me:

"item" is not defined.

Are there tools, techniques or coding styles that help me get more information about the binding problem?

10条回答
爷的心禁止访问
2楼-- · 2019-01-15 23:59

If you are developing in Visual studio and IE I like this more data-bind="somebinding:(function(){debugger; return bindvalue; })()" I like it more then echo function since it will go to the script with all the bindings rather the the eval file and you can just look at the $context $data(I use this in Chrome as well);

查看更多
萌系小妹纸
3楼-- · 2019-01-16 00:05

One thing that I do quite often when there is an issue with what data is available at a certain scope is to replace the template/section with something like:

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

Or, if you want a slightly more readable version:

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

This will spit out the data that is being bound at that scope and let you make sure that you are nesting things appropriately.

Update: as of KO 2.1, you can simplify it to:

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

Now the arguments are passed on to JSON.stringify.

查看更多
The star\"
4楼-- · 2019-01-16 00:08

I found another one that can be helpfull. I was debugging some bindings and tried using Ryans example. I got an error that JSON found a circular loop.

<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>

But, using this approach a replaced the data-bind value with the following:

  <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>

Now if i click on the PRE element while having the chrome debug window open, I get a nicely filled scope variables window.

Found a little better way for it:

<pre data-bind="text: ko.computed(function() { debugger; })"></pre>
查看更多
Evening l夕情丶
5楼-- · 2019-01-16 00:08

Check out a really simple thing I use:

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

Or

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

Then in html, say, you had:

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

Just replace it with

<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>

Enjoy :)

UPDATE

Another annoying thing is when you are trying to bind to an undefined value. Imagine in the example above that the data object is just {} not { value: 'some text' }. In this case you will be in trouble, but with the following tweak you will be fine:

<div data-bind="text: $data['value']"></div> 
查看更多
一纸荒年 Trace。
6楼-- · 2019-01-16 00:12

Define a bindingHandler once, somewhere in your JavaScript library files.

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

than simply use it likes this:

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

Advantages

  • Use the full power of the Chrome debugger, like Reveal in Elements Panel
  • You don't have to add custom elements to your DOM, just for debugging

enter image description here

查看更多
Ridiculous、
7楼-- · 2019-01-16 00:16

The easiest way to see what data are passed to binding is to drop the data to console:

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

Knockout will evaluate value for text binding (any binding can be used here in fact) and flushes $data to console browser panel.

查看更多
登录 后发表回答