Я определил модель представления под названием model.customDifficultySettings
, часть которой показана ниже. Он использует расширитель с прецизионной точностью, который является просто переименованной версией примера расширителя для округления до десятичных дробей X, показанных в документации Knockout.js.
ko.extenders.precision = function(target, precision) {
//create a writable computed observable to intercept writes to our observable
var result = ko
.pureComputed({
read: target, //always return the original observables value
write: function(newValue) {
var current = target(),
roundingMultiplier = Math.pow(10, precision),
newValueAsNum = isNaN(newValue) ? 0 : +newValue,
valueToWrite =
Math.round(newValueAsNum * roundingMultiplier) / roundingMultiplier;
//only write if it changed
if (valueToWrite !== current) {
target(valueToWrite);
} else {
//if the rounded value is the same, but a different value was written, force a notification for the current field
if (newValue !== current) {
target.notifySubscribers(valueToWrite);
}
}
}
})
.extend({ notify: "always" });
//initialize with current value to make sure it is rounded appropriately
result(target());
//return the new computed observable
return result;
};
model.customDifficultySettings = {
econBase: ko
.observable(0)
.extend({ rateLimit: { timeout: 750 }, precision: 3 }),
};
В более поздней функции makeGame()
мы гарантируем, что наша model.customDifficultySettings.econBase()
наблюдаемый соответствует значению выбранного значения сложности
model.customDifficultySettings.econBase(
difficultyInfo[model.newGameDifficultyIndex() || 0].econBase
);
console.log(model.customDifficultySettings.econBase());
console.log(difficultyInfo[model.newGameDifficultyIndex() || 0].econBase);
Значение difficultyInfo[model.newGameDifficultyIndex()].econBase
при первом запуске составляет 0,55. Я ожидаю, что консоль будет либо показывать оба значения как 0,55, либо, если что-то пошло не так, оба значения равны 0. Но возвращаемое значение равно 0 для наблюдаемого, но 0,55 для значения, вводимого в него.
Если язапросите наблюдаемое из консоли после запуска кода, он возвращает ожидаемое значение 0,55.
Если уровень сложности изменяется, что приводит к повторному запуску makeGame()
, все значения устанавливаются правильно. Эта проблема возникает только при первом запуске.
Я отследил проблему до точного расширителя. Удалите расширитель и все работает как положено. Но так как я только что скопировал код примера, мне не совсем понятно, что он делает и, следовательно, почему эта проблема возникает.
В качестве обходного пути я мог бы установить все наблюдаемые значения по умолчанию, чтобы они соответствовали значениям по умолчаниютрудный уровень, но я бы предпочел избежать этого.