knockout.js - dados de array aninhados e ligação em cascata de listas suspensas pré-preenchidas em cascata

Eu sou bastante novo no knockout.js, no entanto, eu tenho sido feliz em usá-lo no meu projeto ASP.NET MVC 4, até que eu corri para este obstáculo que tem me incomodado por um tempo, não consigo colocar o meu dedo sobre ele.

O cenário em que estou trabalhando requer várias combinações de dados de localização (região, país, cidade), ou seja, listas suspensas em cascata, o que não é um problema para fazer ao inserir dados novos, mas tive problemas ao tentar para editar os dados salvos.

Os dados estão no formato JSON, com matrizes aninhadas, se parecem com isso (encurtados para propósitos de ilustração):

var newData = 
[
  {
    "ID":1,
    "Name":"Australia and New Zealand",
    "Countries":[
      {
        "ID":13,
        "Name":"Australia",
        "Cities":[
          {
            "ID":19,
            "Name":"Brisbane"
          },
          {
            "ID":28,
            "Name":"Cairns"
          },
...

Eu suspeito que não posso carregar os dados (ou mais claramente, paraligar corretamente), pois estou tendo problemas para acessar a sub-matriz da Região (que contém os Países da Região) e a sub-matriz de Países (que contém as Cidades dos Países).

Depois, há a questão de ter opções pré-preenchidas, o que funciona parcialmente, o viewmodel carrega o número de linhas, mas não seleciona nada.

Aqui está a VM:

   var existingRows = [
    {
        "Region": 1,
        "Country": 13,
        "City": 19
    },
    {
        "Region": 1,
        "Country": 158,
        "City": 3
    }];

   var Location = function (region, country, city) {
       var self = this;
       self.region = ko.observable(region);
       self.country = ko.observable(country);
       self.city = ko.observable(city);

       // Whenever the region changes, reset the country selection
       self.region.subscribe(function () {
           self.country(undefined);
       });

       // Whenever the country changes, reset the city selection
       self.country.subscribe(function () {
           self.city(undefined);
       });
   };

   var LocationViewModel = function (data) {
       var self = this;

       self.lines = ko.observableArray(ko.utils.arrayMap(data, function (row)
       {
           var rowRegion = ko.utils.arrayFirst(newData, function (region)
           {
               return region.ID == row.Region;
           });
           var rowCountry = ko.utils.arrayFirst(rowRegion.Countries, function (country) {
               return country.ID == row.Country;
           });
           var rowCity = ko.utils.arrayFirst(rowCountry.Cities, function (city) {
           return city.ID == row.City;
           });
           return new Location(rowRegion, rowCountry, rowCity);
       }));

       // Operations
       self.addLine = function () {
           self.lines.push(new Location())
       };
       self.removeLine = function (line) {
           self.lines.remove(line)
       };
   };

   var lvm = new LocationViewModel(existingRows);

   $(function () {
       ko.applyBindings(lvm);
   });

Código HTML:

<tbody data-bind="foreach: lines">
    <tr>
        <td><select data-bind="options: newData, optionsText: 'Name', optionsValue: 'ID', optionsCaption: 'Select a region...', attr: { name: 'SubRegionIndex' + '['+$index()+']' }, value: region"></select></td>
        <td><select data-bind="options: Countries, optionsText: 'Name', optionsValue: 'ID', optionsCaption: 'Select a country...', attr: { name: 'CountryIndex' + '['+$index()+']' }, value: country"></select></td>
        <td><select data-bind="options: Cities, optionsText: 'Name', optionsValue: 'ID', optionsCaption: 'Select a city...', attr: { name: 'CityIndex' + '['+$index()+']' }, value: city"></select></td>
        <td><a href='#' data-bind='click: $parent.removeLine'>Remove</a></td>
    </tr>    
</tbody>

Eu tentei modificar o exemplo do editor de carrinho do site knockout.js com dados pré-preenchidos, mas não fiz muito progresso, pareço estar faltando alguma coisa. Realmente não encontrei nada com matrizes aninhadas, então estou preso aqui ...

Eu coloquei o código completo no JSFiddle aqui:http://jsfiddle.net/fgXA2/1/

Qualquer ajuda seria apreciada.

questionAnswers(1)

yourAnswerToTheQuestion