Есть ли способ заставить нокаут ждать, чтобы пересчитать вычисленные значения, пока не будет определена модель представления?
У меня есть сложная модель представления, которая представляет собой пару сотен строк кода JavaScript с хорошим количеством наблюдаемых свойств, вычисляемых наблюдаемых свойств, доступных для записи вычисляемых наблюдаемых свойств и функций. Так что справиться с этим довольно сложно.
Раздражающая проблема, с которой мне пришлось столкнуться, заключается в том, что вычисляемые наблюдаемые значения вычисляются сразу же, как только вы их определили. Таким образом, использование переменных, которые еще не определены в модели представления в момент определения наблюдаемой, приводит к ошибкам, утверждающим, что переменная не была определена. Это ... только позже в файле.
Вот надуманный пример:
function ViewModel1(args) {
var self = this;
self.firstName = ko.observable(args.firstName);
self.lastName = ko.observable(args.lastName);
self.fullName = ko.computed(function () {
return self.firstName() + ' ' + self.lastName();
});
}
function ViewModel2(args) {
var self = this;
self.fullName = ko.computed(function () {
// uh oh, where's firstName?
return self.firstName() + ' ' + self.lastName();
});
self.firstName = ko.observable(args.firstName);
self.lastName = ko.observable(args.lastName);
}
С помощьюViewModel1
будет работать без проблем. В точкеfullName
определено,firstName
а такжеlastName
определяется так, что он работает как ожидалось. С помощьюViewModel2
не будет работать. В вычисляемой функции будет ошибкаfirstName
не определено.
То, что я делал до сих пор, состояло в том, чтобы гарантировать, что все вычисляемые наблюдаемые могут быть определены после того, как все зависимые переменные были определены. Проблема в том, что при этом вещи определяются в казалось бы случайных местах, когда я предпочел бы хранить связанные переменные, определенные близко друг к другу.
Одно хорошее решение, которое я придумал, состоит в том, чтобы определить «инициализацию». наблюдаемый наборtrue
и проверяют все вычисляемые наблюдаемые, если они все еще инициализируются, вычисляют и возвращают значение, когда оно не является. Таким образом, попытки доступа к неопределенной в данный момент переменной не будут предприняты.
function ViewModel3(args) {
var self = this;
var initializing = ko.observable(true);
self.fullName = ko.computed(function () {
if (!initializing()) {
return self.firstName() + ' ' + self.lastName();
}
});
self.firstName = ko.observable(args.firstName);
self.lastName = ko.observable(args.lastName);
initializing(false);
}
Но в моем случае это не будет очень практичным. У меня есть много вычисляемых наблюдаемых, поэтому выполнение этого во всех из них сделает его очень раздутым, помните, у меня их много. Дросселирование, похоже, не имеет значения.
Is there a way to tell knockout to wait before trying to calculate the values of computed observables? Or is there a better way for me to structure my code to deal with this?
Я мог бы, вероятно, создать некоторые вспомогательные функции для управления логикой инициализации, но мне все равно придется изменить все вычисленные наблюдаемые определения. Я полагаю, что я могу изменить выбивание патча, чтобы добавить эту инициализирующую логику, поскольку я не знаю, что выбивка имеет такие опции, которые я мог бы просто сделать. Я смотрел на источник для вычисляемых наблюдаемых ранее, но я не знаю, есть ли уже установка в другом месте.