knockout.js中的自定义节流扩展器

时间:2012-11-03 09:07:12

标签: knockout.js throttling extender computed-observable

我有一个可以观察到与某些输入绑定的可观察量,有时它的值变化太快,因此最终用户没有时间阅读它。所以我想限制输入变化的速度。

但它不是油门,因为油门是一个瓶颈,受限制的可观测量在变化时根本不会改变。我希望有一个自定义限制,以便第一个更改立即应用,然后它可能只在延迟后更改(当然,每次延迟后它显示CURRENT值)。

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

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;
        }
    });
}

问题是我希望它也能用于计算的observable。对于他们,throttle extender有throttleEvaluation变量,这个变量用于dependentObservable.js evaluatePossiblyAsync方法。但我不想改变核心淘汰文件中的任何内容。

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

1 个答案:

答案 0 :(得分: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),这让我在测试我添加的更改时刮过头,直到我注意到它为止。

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