Knockout Могу ли я обойти этот вычисляемый цикл?

У меня есть следующая структура для группы объектов в моей модели представления

У меня есть базовый массив, заполненный объектами, в которых есть элементы ko.observable.

Пример: selections = [{Ноги:{'0':ko.observable(12)}}, {Ноги:{'0':ko.observable(0)}}]

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

Кэш используется как хранилище двоичных файлов 12 == 1100 == Флажки 3 и 4 отмечены

Теперь все это я могу заставить работать без проблем, мне, очевидно, даже не нужно делать Cache наблюдаемым.

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

То, что ниже, вроде как работает, но создает цикл, с которым нокаут прекрасно справляется, но его результаты ненадежны, и это замедляет работу.

Как создать эту настройку привязки?

function Runner(name, odds, race, leg, post) {
    var runner = {
        Name: name,
        Odds: odds,
        Post: post,
        Race: race,
        Leg: leg,
        Cache: selections[race].Legs[leg],
        Selected: ko.observable(false),
        Enabled: ko.observable(true),
        Valid: true
    };

    runner.Check = ko.computed(function() {
        if (!this.Enabled.peek() || !this.Valid ) return;
        var checked = this.Selected();
        var cache = this.Cache();

        if (checked) {
            this.Cache(cache | 1 << this.Post);
        } else {
            this.Cache(cache & ~(1 << this.Post));
        }

    }, runner);

    return runner;
}

Изменить

<input type="checkbox" data-bind="checked: Selected, enable: Enabled"/>

person Zholen    schedule 20.04.2013    source источник
comment
Я не могу понять, как вычисленный чек должен относиться к бегуну. Можете ли вы показать нам свою разметку или создать скрипку для демонстрации?   -  person CodeThug    schedule 20.04.2013
comment
Пользователь нажимает флажок -> Выбранные изменения для соответствия -> Проверка срабатывает, так как выбранное изменено -> Устанавливает правильный битовый флаг в кэше -> (начало цикла здесь) Вызывает проверку с момента изменения кэша и т. д. О, я думаю, я мог бы добавить строку, в которой говорилось : проверить значение бита и если оно такое же, как Selected уже тогда ничего не делать, что бы выйти из цикла да?   -  person Zholen    schedule 20.04.2013


Ответы (1)


У меня был момент ясности после того, как я написал свой вопрос. Но я думаю, что это хороший вопрос, тем не менее, поэтому вместо того, чтобы изменить или удалить мой вопрос, я просто опубликую свое новейшее решение и, надеюсь, получу критику.

Итак, в конце концов, я полностью отказываюсь от выбранного значения

Примечание. this.Post + 1 зависит от моих потребностей, обычно он не нужен, я просто хочу оставить первый бит неиспользованным для будущего использования.

    runner.Check = ko.computed({
        read: function() {
            var cache = ko.utils.unwrapObservable(this.Cache); //Edit 1
            return cache & 1 << (this.Post + 1);
        },
        write:function(value) {
            var cache = this.Cache();
            if (!this.Enabled.peek() || !this.Valid || this.Post === -1) return;
            var mask = 1 << (this.Post+1);
            if(value === !(cache & mask)){ //Edit 2
                this.Cache(value ? cache | mask : cache & ~mask);
            }
        }
    }, runner);

Одна плохая вещь в том, чтобы делать что-то таким образом, это то, что если у меня есть 20 бегунов, которые все используют один и тот же кеш, тогда, когда пользователь выбирает 1 из них, все 20 будут перепроверять себя...

В моем конкретном случае будущие изменения могут заключаться в удалении Peek on Enabled и выполнении проверки, которая говорит, что если !Enabled, то отключите этот бит по умолчанию, а не разрешите флажок Disabled Checked.

Изменить

Изменена функция «чтения» для использования unwrapObservable() в случае, если кэш очищается способами удаления/удаления наблюдаемого в другом месте.

Изменить 2

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

person Zholen    schedule 20.04.2013