Есть ли способ заставить нокаут ждать, чтобы пересчитать вычисленные значения, пока не будет определена модель представления?

У меня есть сложная модель представления, которая представляет собой пару сотен строк кода 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?

Я мог бы, вероятно, создать некоторые вспомогательные функции для управления логикой инициализации, но мне все равно придется изменить все вычисленные наблюдаемые определения. Я полагаю, что я могу изменить выбивание патча, чтобы добавить эту инициализирующую логику, поскольку я не знаю, что выбивка имеет такие опции, которые я мог бы просто сделать. Я смотрел на источник для вычисляемых наблюдаемых ранее, но я не знаю, есть ли уже установка в другом месте.

демоверсия jsfiddle

Ответы на вопрос(1)

Ваш ответ на вопрос