【发布时间】:2016-05-18 19:07:11
【问题描述】:
我正在使用 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)后,我看到“顶级(例如,vm.AllUsd(),包含每个客户 Usd MoneyAccounts 的总和)”上的 ComputedObservables 没有刷新. Sum 仍然是 0。我需要做什么才能在 JS-Structure 的映射中计算这个总量?
我已经尝试使用 dummy-observables 来实现这一点,但这会极大地减慢加载过程(浏览器不堪重负,挂断)
提前致谢
更新:例如,这个例子。我发现,初始化后 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);
})
【问题讨论】:
-
你能添加你用来创建 ViewModel 的代码吗?需要注意的一点是 ko.mapping.fromJS() 每次调用都会创建一个新的引用。因此,如果您调用 vm.clientList = ko.mapping.fromJS(vm.clientsRawData) 并创建一些 observables,那么如果您再次调用 vm.clientList = ko.mapping.fromJS(vm.clientsRawData),它会创建一个新的引用,但是计算出的 observables 仍将指向旧的引用。
-
请rollback the question to version 2 并将解决方案作为答案发布在下面:让其他人更容易发现。
-
@Jeroen 完成。感谢您的反馈。
标签: javascript jquery mvvm knockout.js