KnockoutJS - Как работают вычисляемые наблюдаемые с условными операторами?

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

Всякий раз, когда вы объявляете вычисленное наблюдение, КО немедленно вызывает его чтобы получить его начальное значение. Пока ваш оценщик функция работает, KO ведет журнал любых наблюдаемых (или вычисленных наблюдаемые), что ваш оценщик читает значение.

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

Я создал эту скрипту, чтобы проверить:

http://jsfiddle.net/bJK98/

var ViewModel = function(first, last) {
    this.firstName = ko.observable(first);
    this.lastName = ko.observable(last);
    this.condition = ko.observable(false);

    // at the point of evaluation of this computed observabled, 'condition'
    // will be false, yet the dependecy to both firstName and lastName is
    // identified
    this.fullName = ko.computed(function() {
        return this.condition() ? this.firstName() : this.lastName();
    }, this);
};

Однако каким-то образом Knockout правильно идентифицировал зависимость как от firstName, так и от lastName.

Может кто-нибудь объяснить, как?

Ответ 1

Зависимости

отслеживаются снова каждый раз, когда переопределяется зависимое значение Observable. Итак, если у вас есть условная логика, то ветвь, которая не попала, не будет влиять на зависимости.

В вашей скрипке, если вы отредактируете firstName, тогда значение не будет обновлено, пока вы не переключите condition. В этот момент lastName больше не является зависимостью, поэтому изменения в нем не вызывают зависимое значение Observable.

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

Ответ 2

В нокаут-зависимостях отслеживаются через него одну переменную отслеживания ko.dependencyDetection.

  • Поэтому всякий раз, когда вы объявляете вычисленную переменную, Knockout немедленно вызывает свою функцию оценщика, чтобы получить ее начальное значение и зависимости.
  • Таким образом, во время этого первого вызова он регистрирует его зависимости от переменных lastName и condition.
  • Теперь, когда изменяется lastName, он обновляет все зависимые значения.
  • И всякий раз, когда изменяется condition, он снова запускает функцию оценщика и обновляет все зависимости. Поэтому он добавит firstName в качестве зависимости и удалит lastName.

Таким образом, отслеживание зависимостей работает в нокауте.