Вычисленное возвращаемое значение для другой модели представления в нокауте js

#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 на a pureComputed ?