Подтвердить что ты не робот

Изменение наблюдаемых, но не уведомлять подписчиков в knockout.js

Есть ли способ игнорировать подписчиков при изменении значения наблюдаемого. Id хотел бы изменить значение наблюдаемого, но не выполнить его для подписчиков с knockout.js

4b9b3361

Ответ 1

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

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

Вот расширения, которые добавляют эту функцию к наблюдаемому:

ko.observable.fn.withPausing = function() {
    this.notifySubscribers = function() {
       if (!this.pauseNotifications) {
          ko.subscribable.fn.notifySubscribers.apply(this, arguments);
       }
    };

    this.sneakyUpdate = function(newValue) {
        this.pauseNotifications = true;
        this(newValue);
        this.pauseNotifications = false;
    };

    return this;
};

Вы добавили бы это к наблюдаемому, например:

this.name = ko.observable("Bob").withPausing();

Затем вы можете обновить его без уведомлений, выполнив следующие действия:

this.name.sneakyUpdate("Ted");

Ответ 2

Еще более простой подход:

ko.observable.fn.silentUpdate = function(value) {
    this.notifySubscribers = function() {};
    this(value);
    this.notifySubscribers = function() {
        ko.subscribable.fn.notifySubscribers.apply(this, arguments);
    };
};

Используйте его следующим образом:

this.status = ko.observable("Happily Married");
this.walkIntoBar();
this.status.silentUpdate("Single");
this.walkOutOfBar(); // careful with exceptions
this.status.silentUpdate("Happily Married");

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

Ответ 3

Мне нравится решение, предоставленное @RP Niemeyer, когда все подписчики должны быть проигнорированы. Однако для моего случая у меня есть наблюдаемый с 2-сторонними привязками на элементе управления Select. При использовании @RP Niemeyer элемент управления Select не обновляется. Поэтому мне действительно нужен был способ отключить конкретных наблюдателей, не все. Вот обобщенное решение для этого случая.

Добавьте методы расширений для "тихой" подписки и "тихой" записи.

ko.observable.fn.ignorePokeSubscribe = function (callback, thisValue, event){
    var self = this;
    this.subscribe(function(newValue) {
        if (!self.paused)
            callback(newValue);
    }, thisValue, event);
    return this;
};
ko.observable.fn.poke = function (newValue) {
    this.paused = true;
    var result = this(newValue);
    this.paused = undefined;
    return result;
};

Вы подпишитесь на наблюдаемые, например:

this.name = ko.observable("Bob");
this.name.ignorePokeSubscribe(function(newValue) { /* handler */ }));

Затем вы можете обновить его без специальных уведомлений, выполнив следующие действия:

this.name.poke("Ted");   // standard subscribers still get notified

Ответ 4

Я пришел к этому вопросу, потому что я строил выгружаемый файл данных. Было показано только 10 строк, и каждая строка имеет флажок. В заголовке таблицы был флажок (de) select all.

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

Казалось, что KO обновил html 1000 раз, хотя только 10 наблюдаемых были привязаны к HTML.

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

http://knockoutjs.com/documentation/deferred-updates.html