【问题标题】:Custom throttle extender in knockout.jsknockout.js 中的自定义油门扩展器
【发布时间】:2012-10-23 20:19:21
【问题描述】:

我有一个绑定到某个输入的 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。我应该怎么做才能让它像第一个一样工作?

【问题讨论】:

    标签: knockout.js throttling extender computed-observable


    【解决方案1】:

    对现有代码的快速思考:

    在您的扩展器中,您可以查看您是否正在处理不可写的计算 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),这让我在测试我添加的更改时摸不着头脑,直到我注意到它为止。

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

    【讨论】:

    • 非常感谢!!!我为这个错误道歉,这可能也是我坚持这个的原因。
    猜你喜欢
    • 1970-01-01
    • 2022-01-09
    • 2019-11-29
    • 1970-01-01
    • 2012-09-20
    • 1970-01-01
    • 2016-06-22
    • 1970-01-01
    • 2014-03-09
    相关资源
    最近更新 更多