Knockout JS подписаться на 2 наблюдаемых таким образом, что если один из этих двух изменится, я получу уведомление только один раз - PullRequest
0 голосов
/ 01 апреля 2020

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

Ответы [ 2 ]

1 голос
/ 01 апреля 2020

В KO 3.4.0+ вы можете использовать отложенные обновления для вычислений, которые опираются на start и end таким образом, что это вызывает изменение, даже если start и end изменены дополнительными способами:

let eitherX = 1;
const either = ko.computed(() => {
    start();
    end();
    return ++eitherX;
});
either.extend({deferred: true});

Live Пример:

const start = ko.observable(10);
const end = ko.observable(20);
let eitherX = 1;
const either = ko.computed(() => {
    start();
    end();
    return ++eitherX;
});
either.extend({deferred: true});

console.log("Subscribing");
// Setting deferred
either.subscribe(() => console.log("notified"));
console.log("changing start");
start(11);
console.log("changing end");
end(19);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

В более ранних версиях вы можете использовать ограничение скорости из 0:

let eitherX = 1;
const either = ko.computed(() => {
    start();
    end();
    return ++eitherX;
});
either.extend({rateLimit: 0});

Live Example :

const start = ko.observable(10);
const end = ko.observable(20);
let eitherX = 1;
const either = ko.computed(() => {
    start();
    end();
    return ++eitherX;
});
either.extend({rateLimit: 0});

console.log("Subscribing");
// Applying the rate limit
either.subscribe(() => console.log("notified"));
console.log("changing start");
start(11);
console.log("changing end");
end(19);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

Вам нужно eitherX, чтобы значение either всегда отличалось при повторном вычислении. Если вы попытались определить either в терминах start и end (например, start() + end()), если вы изменили start и end дополнительными способами (добавив один к start и вычтя один из end) значение either не изменится, и вы не получите уведомление.

0 голосов
/ 06 апреля 2020

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

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

Единственная альтернатива - добавить кнопку после 2 входных фильтров с надписью «Подтвердить фильтр» и инициировать обратный вызов для этого.

На самом деле, есть другой способ, но он включает в себя эффективное выполнение двух обратных вызовов с сначала отменяется в середине - go, когда срабатывает 2-й, и это, вероятно, то, чего вам следует избегать sh, верно?

...