Build knockout model and view dynamically, radio b

2019-03-02 10:58发布

问题:

I am in the process of making one of my previous questions fully dynamic in that the model is built from server data, and the view loops through the viewmodel via the knockout ko foreach functionality.

The problems I am facing are:

  1. The radio options don't stay with the value set, i.e. I click on the Operating System, and then select a Database option, and then the Operating System setting disappears.

  2. The dependent options (in this case database and clustering) do not have their initial selection selected when the dependent option changes (i.e. when OS changes, DB should go back to the first option, none).

My fiddle is here and i think the problem is either related to the code below:

 computedOptions.subscribe(function () {
                    var section = this;
                    console.log("my object: %o", section);   
                    section.selection(section.options()[0].sku);
                },section);

Or my view bindings:

<!-- ko foreach: selectedOptions -->
    <h3><span data-bind="text: description"></span></h3>
    <table class="table table-striped table-condensed">
        <thead>
            <tr>
                <th colspan="2" style="text-align: left;">Description</th>
                <th>Price</th>
            </tr>
        </thead>
        <tbody>
            <!-- ko foreach: options -->
            <tr>
                <td><input type="radio" name="$parent.name" data-bind="checkedValue: $data, checked: $parent.selection" /></td>
                <td style="text-align: left;"><span data-bind="text: name"></span></td>
                <td style="text-align: left;"><span data-bind="text: price"></span></td>
            </tr>
            <!-- /ko -->
        </tbody>
    </table>
<!-- /ko -->

I am not sure which and would appreciate a fresh eyes as my brain hurts from the jsfiddle session.

回答1:

You have two problems:

  • You are not correctly binding your radio button's names: name="$parent.name" is not a knockout binding expression and it just assigns the string "$parent.name" to all of your radio buttons. What you need is to use the attr binding:

    <input type="radio" data-bind="checkedValue: $data, 
                                   checked: $parent.selection, 
                                   attr: { name: $parent.name }" />
    
  • The initial selection is not working because you are using the checkedValue: $dataoption this means that your checked should contain the whole object and not just one property (sku) so you need to change your computedOptions.subscribe to:

    computedOptions.subscribe(function () {
        var section = this; 
        section.selection(section.options()[0]);
    },section);
    

Demo JSFiddle.