У меня сложная модель представления, которая представляет собой пару сотен строк кода 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 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
и сделать все вычисленные тесты наблюдаемых, если он все еще инициализирует и вычисляет и возвращает значение, когда это не так. Таким образом, попытки доступа к текущей переменной undefined не будут выполнены.
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);
}
Но в моем случае это будет не очень практично. У меня много вычислимых наблюдаемых, поэтому делать это во всех из них будет очень раздутым, помните, что у меня их много. Дросселирование, похоже, не имеет значения.
Есть ли способ сказать нокауту подождать, прежде чем пытаться вычислить значения вычисленных наблюдаемых? Или у меня есть лучший способ структурировать мой код, чтобы справиться с этим?
Я мог бы, вероятно, сделать некоторые вспомогательные функции для управления логикой инициализации, но мне все равно пришлось бы изменять все вычисляемые наблюдаемые определения. Я полагаю, что я могу использовать нокаут для патчей, чтобы добавить эту логику инициализации, поскольку я не знаю, что нокаут имеет такие параметры, которые я мог бы просто сделать. Я раньше смотрел на источник для вычисляемых наблюдаемых данных, но не знаю, есть ли еще какой-либо параметр в другом месте.