Нокаутированная проблема рекурсивного отображения
Этот пост является продолжением этого.
Я обновил код следующим образом:
viewModel.getQuotesSuccess = function (result) {
var myCoverQuotesViewModel = function (data) {
var self = this;
ko.mapping.fromJS(data, {}, self);
self.Childs = ko.observableArray(ko.utils.arrayMap(data.Childs, function (c) {
return new myCoverQuotesViewModel(c);
}));
self.selectedChild = ko.observable();
self.showChildren = ko.computed(function () {
return self.selectedChild()
&& self.selectedChild().Childs().length > 0;
});
var mapping = {
'CoverQuotes': {
create: function (options) {
return new myCoverQuotesViewModel(options.data);
}
}
}
ko.mapping.fromJS(result, mapping, viewModel);
};
ViewModel будет выглядеть примерно так:
var viewModel = {
CoverQuotes: [{id: 1, label:'test', Childs:[{id: 2, label:'child1'}]]
};
Итак, в двух словах, у меня есть массив CoverQuotes, каждый элемент которого также содержит массив CoverQuotes (и так далее).
Проблема, с которой я столкнулся, связана с наблюдаемым массивом Childs. При звонке:
return new myCoverQuotesViewModel(options.data);
для основного объекта все работает нормально. Однако при вызове конструктора из функции arrayMap эта строка:
ko.mapping.fromJS(data, {}, self);
ничего не делает
В результате вложенным дочерним элементам назначаются свойства selectedChild и showChildren, но они пропускают все остальные (например, идентификатор и метку в этом примере).
Что мне не хватает, так что отображение также работает для детей?
1 ответ
Я решил свою проблему с помощью рекурсивного пользовательского отображения
viewModel.getQuotesSuccess = function (result) {
var myCoverQuotesViewModel = function (data) {
var self = this;
var mappingChildren = {
'Childs': {
create: function (options) {
return new myCoverQuotesViewModel(options.data);
}
}
}
ko.mapping.fromJS(data, mappingChildren, self);
self.selectedChild = ko.observable();
self.showChildren = ko.computed(function () {
return self.selectedChild() && self.selectedChild().Childs().length > 0;
});
self.IsVisible = ko.computed({
read: function () {
var visible = true;
if (self.DependsOn().length > 0) {
$.each(self.DependsOn(), function (index, value) {
var dependency = viewModel.QuoteSelectedViewModel().CoverQuotes.filterByProperty("Code", value);
if (dependency().length > 0) {
visible = visible & dependency()[0].IsSelected();
} else {
visible = false;
}
});
}
return visible;
},
deferEvaluation: true
}, this);
}
var mapping = {
'CoverQuotes': {
create: function (options) {
return new myCoverQuotesViewModel(options.data);
}
}
}
ko.mapping.fromJS(result, mapping, viewModel);
};