0

我有一个绑定到某些输入的 observable,有时它的值变化太快,以至于最终用户没有时间阅读它。所以我想限制输入变化的速度。

但这不是一个节流阀,因为节流阀是一个瓶颈,节流的 observable 在变化的同时根本没有变化。我想要一个自定义油门,以便立即应用第一个更改,然后它可能仅在延迟后更改(当然,每次延迟后它都会显示 CURRENT 值)。

到目前为止,我已经编写了自定义的 restrictSpeedChange 扩展程序。这是:http: //jsfiddle.net/kasheftin/Pn9r8/4/。它实际上适用于通常的 observables。

ko.extenders.restrictChangeSpeed = function(target,timeout) {
    var writeTimeoutInstance = null;
    var currentValue = target();
    var updateValueAgain = false;
    return ko.dependentObservable({
        read: target,
        write: function(value) {
            var updateValue = function(value) {
                target(value);
                if (!writeTimeoutInstance) {
                    writeTimeoutInstance = setTimeout(function() {
                        writeTimeoutInstance = null;
                        if (updateValueAgain) {
                            updateValueAgain = false;
                            updateValue(currentValue);
                        }
                    },timeout);
                }
            }
            currentValue = value;
            if (!writeTimeoutInstance)
                updateValue(currentValue);
            else
                updateValueAgain = true;
        }
    });
}

问题是我希望它也可以与计算的 observables 一起使用。对他们来说,throttle extender 有throttleEvaluation 变量,这个变量在dependentObservable.js evaluatePossiblyAsync 方法中使用。但我不想更改核心淘汰文件中的任何内容。

在我的示例http://jsfiddle.net/kasheftin/Pn9r8/4/中,通常的可观察变量是 restrictChangeSpeedVar1 并且它按预期工作。计算变量是restrictChangeSpeedComputedVar1。我应该怎么做才能让它像第一个一样工作?

4

1 回答 1

3

快速思考一下您现有的代码:

在您的扩展器中,您可以查看是否正在处理不可写的计算 observable,然后返回一个已通过扩展器并订阅了计算的 observable。

ko.extenders.restrictChangeSpeed = function(target, timeout) {
    var writeTimeoutInstance = null;
    var currentValue = target();
    var updateValueAgain = false;
    var interceptor;

    if (ko.isComputed(target) && !ko.isWriteableObservable(target)) {
        interceptor = ko.observable().extend({ restrictChangeSpeed: timeout });
        target.subscribe(interceptor);
        return interceptor;
    }
....

关键是你需要一些东西来完成你的“写”逻辑。使用普通计算,它只会重新评估其“读取”逻辑并更新,而不会通过您的“写入”代码。

这是一个示例:http: //jsfiddle.net/rniemeyer/GPbrR/

此外,您的小提琴中有一个错字:

self.restrictChangeSpeedComputedVar1 = ko.computed(this.var1).extend({restictChangeSpeed:1000});

您拼错了您的扩展程序名称(restict而不是restrict),这让我在测试我添加的更改时摸不着头脑,直到我注意到它。

关于我的更改的唯一有趣的事情是,现在有人可能会写入您的计算,但是每当底层计算发生更改时它总是会更新,我不明白您为什么会故意尝试写入它。

于 2012-11-03T18:14:56.240 回答