在ko.mapping.fromJS之后,ComputedObservables不会重新计算

时间:2016-02-08 23:17:50

标签: javascript jquery mvvm knockout.js

我正在使用KnockoutJS,我在每个级别都有一个嵌套的ViewModel-Structure和Computed Observables。父级别包含其子级的累计。数据结构看起来像这样(简单):

vm.clientsRawData = [
    {
        ClientName: "Thomas",
        MoneyAccounts: [
            {
                Currency: "USD",
                Amount: "1000"
            }
            {
                Currency: "EUR",
                Amount: "2000"
            }
        ]
    },
    {
        ClientName: "Ann",
        MoneyAccounts: [
            {
                Currency: "CHF",
                Amount: "4000"
            }
            {
                Currency: "EUR",
                Amount: "1500"
            }
        ]
    }
]

在初始化ViewModel之后(使用ko.mapping.fromJS)我看到“Top-Level(例如,vm.AllUsd(),包含每个客户端Usd MoneyAccounts的总和)上的ComputedObservables”没有刷新。 Sum仍为0.我需要做什么来计算JS-Structure映射中的总量?

我已经尝试使用虚拟可观察对象来实现这一点,但这极大地减慢了加载过程(浏览器不堪重负,挂起)

提前致谢

更新:例如,这个例子。我发现,在初始化之后,Client-Count为0。但为什么呢?

var ClientsMapping = {
  create: function (options) {
    var client = ko.mapping.fromJS(options.data, ContainersMapping)
    //Some computed observables for level one here...
    return client;
  }
}
var ContainersMapping = {
  'Containers': {
    create: function (options) {
      var container = ko.mapping.fromJS(options.data, MoneyAccountsMapping)
      container.totalChf = ko.computed(function () {
        var total = 0;
        $.each(container.MoneyAccounts(), function () {
          if (this.Currency() == "CHF") {
            total += this.Amount();
          }
        })
        return total;
      })
      //Some computed observables for level two here...
      return container;
    }
  }
}

var MoneyAccountsMapping = {
  'MoneyAccounts': {
    create: function (options) {
      var macc = new MoneyAccountModel(options.data)
      //Some computed observables for level three here...
      return macc;
    }
  }
}
var ClientModel = function (data) {
  ko.mapping.fromJS(data, {}, this);
}
var ContainerModel = function (data) {
  ko.mapping.fromJS(data, {}, this);
}
var MoneyAccountModel = function (data) {
  ko.mapping.fromJS(data, {}, this);
}
var data = [
  {
    'Clients': 'Thomas',
    'Containers': [
      {
        'ContName': 'Cont01',
        'MoneyAccounts': [
          { Currency: "CHF", Amount: 1000 },
        ]
      }
    ]
  },
{
  'Clients': 'Ann',
  'Containers': [
    {
      'ContName': 'Cont01',
      'MoneyAccounts': [
        { Currency: 'CHF', Amount: 1000 },
        { Currency: 'EUR', Amount: 500 }
      ]
    }
  ]
}
]

function viewModel() {
  var self = this;
  self.clients = ko.observableArray()
  self.clientsCount = ko.computed(function () {
    return self.clients().length
  })
}
var vm;
$(function () {
  vm = new viewModel();
  vm.clients = ko.mapping.fromJS(data, ClientsMapping);
})

1 个答案:

答案 0 :(得分:1)

好的,明白了。我必须像这样调用客户observableArray:

vm.clients(ko.mapping.fromJS(data, ClientsMapping)())

非常感谢Eric指出我正确的方向。你救了我! : - )