0
votes

So what exactly is the ko.observable() doing? Here's the situation. I have a boolean ko.observable(), as you can see. I have click set to that value, so it SHOULD toggle the value of the true false contained within it's method call.

When I watch the array get populated in the developer tools, I see that selected does not = true or false, it instead = a pretty extensive function, and I can't find the true or false value anywhere inside of that, so I have no idea what exactly is happening when ko.observable() is used

What I expected is for tab.selected to be the value of tabArray[tab].selected, and when the page loads, that is correct. However, after clicking, tabArray[tab].selected = [Object object] when the text value is written out. I attempt to use:

<pre data-bind="text: JSON.stringify(ko.toJS(tab.selected)"></pre>

(found here: http://www.knockmeout.net/2013/06/knockout-debugging-strategies-plugin.html) and that prints out either true or false, do I need to do this for the other places where i need that value? Because I'm not sure exactly what ko.observable is doing.

define(['knockout', 'text!../Content/SSB/PartialViews/MainContent.html'], function (ko, MCTemplate) {
    ko.components.register('MainContent', {
        template: MCTemplate
    });

    var MainViewModel = {
        tabArray: [
                { name: 'bob', selected: ko.observable(true) },
                { name: 'bib', selected: ko.observable(false) },
                { name: 'bab', selected: ko.observable(false) },
                { name: 'bub', selected: ko.observable(false) },
                { name: 'beb', selected: ko.observable(false) },
        ]
    };
    ko.applyBindings(MainViewModel);
    return {
        viewModel: MainViewModel
    }
});

the HTML

<div id="tab">

    <ul class="nav nav-tabs" role="tablist">
        <!--ko foreach: {data: $parent.tabArray, as: 'tab'}-->

            <li data-bind="click: tab.selected, css: { 'active': tab.selected}">        
                    <a data-bind="attr: {href: '#' + tab.name}, text: name"></a>
                <div data-bind="text: tab.name"></div>
                <div data-bind="text: tab.selected"></div>
            </li>
        <!--/ko-->
    </ul>
    <!--ko foreach:  {data: $parent.tabArray, as: 'tab'}-->
    <div class="ui-tabpanel" role="tabpanel"  data-bind="visible: tab.selected">
        <p data-bind="text: name"></p>
    </div>
    <!--/ko-->

</div>
1
Knockout observables are functions that can be used to get/set the backing value. Try tab.selected() instead of tab.selected. I use the Knockout-ES5 shim to get around this behavior. - CrimsonChris
If you want to read a observable you should use () convention as you do for methods/functions. - super cool

1 Answers

0
votes

The click binding calls the provided function, passing it the current view model (also called $data). That's why you see [Object object] as the observable's value after the click. Since you want the click to toggle the observable, you need to create a function to do that. A nice, clean way to do this is through a custom binding, which I'll call toggle:

ko.bindingHandlers.toggle = {
    init: function(element, valueAccessor) {
        ko.utils.registerEventHandler(element, 'click', function () {
            var obs = valueAccessor();
            obs(!obs());
        });
    }
};

Now you bind using toggle instead of click: <li data-bind="toggle: tab.selected...