#javascript #knockout.js #knockout-3.0
Вопрос:
Вот моя модель viemodel, чертовски простая:
function collection_rate_vm() {
self = this;
self.rate = ko.observable(0);
self.rate_as_percent = ko.computed(() => {
return (self.rate() * 100).toFixed(2) ' %';
});
}
get_collection_rate_vm = (obj) => {
let vm = new collection_rate_vm();
vm.rate(obj.deduction_percent);
return vm;
}
Коллекция такой модели представления помещается в основную модель представления в виде наблюдаемого массива:
function collection_rates_index_vm() {
var self = this;
self.shown_rates = ko.observableArray([]);
self.edition_vm =ko.observable(new collection_rate_vm());
self.edition_start = (vm) => {
self.edition_vm(vm);
}
self.edition_finish = () => {
let req_body = {
id: self.edition_vm().id(),
...
};
$.ajax({
success: (res) => {
var old = ko.utils.arrayFirst(self.shown_rates(), function (item) {
return item.id() == self.edition_vm().id();
});
self.shown_rates.replace(old, self.edition_vm());
}
});
}
}
Изначально загруженные данные отображаются хорошо. Однако после того, как я отредактирую скорость в любой записи, вычисленное значение rate_as_percent
становится 12.00 %
. После расследования я выяснил, что это будет значение последней виртуальной машины в коллекции.
Если я удалю последний элемент в массиве, значения начнут отображаться, как и ожидалось.
Для отладки я попытался отредактировать значение непосредственно в консоли, и это доказало, что проблема не возникает во внешнем интерфейсе:
> main_vm.shown_rates()[1].rate()
< 0.1104
> main_vm.shown_rates()[1].rate_as_percent()
< "11.04 %"
> main_vm.shown_rates()[1].rate(0.1105)
< collection_rate_vm {id: ƒ, account_id: ƒ, account_number: ƒ, account_description: ƒ, validity_period_type: ƒ, …}
> main_vm.shown_rates()[1].rate()
< 0.1105
> main_vm.shown_rates()[1].rate_as_percent()
< "12.00 %"
Что еще более сбивает с толку, я помещаю точку останова внутри rate_as_percent
функции, и она не срабатывает при вызове функции.
В этот момент я теряюсь. Я подозреваю, что результат вычислений каким-то образом кэшируется, и по какой-то причине возвращается результат для другой модели viemodel. Но я не могу этого понять.
Я использую новейшую версию knockout.js что равно 3.5.0.
Комментарии:
1. Внимательно посмотрите — есть ли где — нибудь еще в вашем JS, где вы устанавливаете
self.rate = ...
, то есть место, где вы намеревались присвоить значение, но на самом деле вы переназначаете все наблюдаемое?2. @awj, я проверил это дважды. Единственное место, где
rate
это установлено, находится в конструкторе. Единственное место, где ему присваивается значение, — это при создании виртуальной машины из ответа api.3. @awj Я добавил некоторый код, который может иметь отношение к делу.
4. У меня нет ответа, я могу только помочь вам отладить. С этой целью: не могли бы вы добавить
self.rate.subscribe(function(val) { console.log(val); });
— это должно прояснить, если и когда кто-то другой обновляетrate
. Кроме того, имеет ли какое-либо значение, если вы переключитесьrate_as_percent
на apureComputed
?