Frank van Eykelen
Frank van Eykelen

Reputation: 1956

How do I copy an item from a ko.mapping.fromJS Array to another property of the viewmodel?

Here's something that used to work in existing code that ran on Knockout 2, that I'm refactoring to Knockout 3.

The properties of the viewmodel are initialized from a feed (simplified code):

$.ajax({
    url: "/api/GetData",
    data: {
        clientId: clientId
    },
    type: "GET",
    dataType: "json",
    contentType: 'application/json; charset=utf-8',
    traditional: true,
    success: function (data) {
        viewModel.periods(ko.mapping.fromJS(data)());
        viewModel.selectedPeriod = ko.observable(viewModel.periods()[0]);
    },
    async: false
});

The viewModel.selectedPeriod = line works when I debug the value, but the binding does not work.

So this fails ...

<ul data-bind="foreach: selectedPeriod.Years">
    <li data-bind="text: Year"></li>
</ul>

... while this works:

<ul data-bind="foreach: periods">
    <li>
        <ul data-bind="foreach: Years">
            <li data-bind="text: Year"></li>
         </ul>
    </li>
</ul>

I've reproduced my problem in a simplified Fiddle: https://jsfiddle.net/frankvaneykelen/w3opn442/12/

Upvotes: 1

Views: 241

Answers (2)

dfperry
dfperry

Reputation: 2258

You need to use the with binding to properly narrow your context:

https://jsfiddle.net/lobotomize/w3opn442/13/

note the with binding on the outer div

    <div class="col-xs-6" data-bind="with: selectedPeriod">
         <h5>selectedPeriod.Years</h5>
        <ul data-bind="foreach: Years">
            <li data-bind="text: Year"></li>
        </ul>
    </div>

Upvotes: 1

Sam.C
Sam.C

Reputation: 1621

Just a few changes to your code ...

viewModel.selectedPeriod(viewModel.periods()[0]); // observable method call instead of assigning

....

 <ul data-bind="foreach: selectedPeriod().Years">  // resolve the observable first ... 

a working code can be found here

https://jsfiddle.net/0cLtvqz0/4/

Upvotes: 2

Related Questions