Advertisements. This binding is used to bind the child elements of an object in the specified object's context. This binding can also be nested with other type of bindings such as if and foreach.
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
.
If you are using Chrome for development, there is a really great extension (with which I'm not affiliated) called Knockoutjs context debugger that shows you the binding context directly in the Developer Tools' Elements panel.
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
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>
>=
icon in the bottom-left of the Chrome Developer
Toolbar, or by opening the "Console" tab in the Chrome Developer
Toolbar, or by pressing Ctrl+Shift+J
ko.dataFor($0)
ko.contextFor($0)
This trick is a combination of Chrome's $0-$4 feature and KnockoutJS's utility methods. In short, Chrome remembers which elements you have selected in the Chrome Developer Toolbar and exposes these elements under the alias $0
, $1
, $2
, $3
, $4
. So when you right-click an element in your browser and select 'Inspect element', this element automagically becomes available under the alias $0
. You can use this trick with KnockoutJS, AngularJS, jQuery or any other JavaScript framework.
The other side of the trick is KnockoutJS's utility methods ko.dataFor and ko.contextFor:
ko.dataFor(element)
- returns the data that was available for binding
against the elementko.contextFor(element)
- returns the entire binding context that was
available to the DOM element.Remember, Chrome's JavaScript Console is a fully functional JavaScript runtime environment. This means that you are not limited to just looking at variables. You can store the output of ko.contextFor
and manipulate the viewmodel directly from the console. Try var root = ko.contextFor($0).$root; root.addContact();
and see what happens :-)
Happy debugging!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With