Javascript 超时后调用Knockout JS Extender函数

Javascript 超时后调用Knockout JS Extender函数,javascript,html,knockout.js,Javascript,Html,Knockout.js,我目前正在尝试使用扩展器在淘汰版JS应用程序中实现自动保存功能。我想在用户停止在字段中键入时调用autosave函数,而不仅仅是当他们从字段中移出时 这是我想在一个可观察对象更新时调用的logChange方法 //KO Extender for logging changes and calling the autosave function ko.extenders.logChange = function (target, precision) { //create a w

我目前正在尝试使用扩展器在淘汰版JS应用程序中实现自动保存功能。我想在用户停止在字段中键入时调用autosave函数,而不仅仅是当他们从字段中移出时

这是我想在一个可观察对象更新时调用的logChange方法

    //KO Extender for logging changes and calling the autosave function
ko.extenders.logChange = function (target, precision) {

    //create a writable computed observable to intercept writes to our observable
    var result = ko.pureComputed({
        read: target,  //always return the original observables value
        write: function (newValue) {
            debugger;
            var current = target(),
                valueToWrite = newValue,
                attName = precision;

            //only write if it changed
            if (valueToWrite !== current) {
                target(valueToWrite);
                //self.autoSave(attName, target());
            } else {
                //if the rounded value is the same, but a different value was written, force a notification for the current field
                if (newValue !== current) {
                    target.notifySubscribers(valueToWrite);
                }
            }
        }
    }).extend({ notify: 'always' });

    //initialize with current value to make sure it is rounded appropriately
    result(target());

    //return the new computed observable
    return result;

};
这就是我在viewmodel中设置observable的方式

    self.controlCenter = ko.observable().extend({ rateLimit: { timeout: 500, method: "notifyWhenChangesStop" }, logChange: "ControlCenter" });
这是我的html标记,用于可观察到的

    <div class="pure-u-1-2 pure-u-md-1-4 pure-u-lg-1-8">
                        <label for="ddlControlCenter">Jurisdiction</label>
                        <input type="text" class="pure-input-1 full-text" list="controlCenterList" data-bind="textInput: controlCenter" />
                        <datalist id="controlCenterList" data-bind="foreach: controlCenters">
                            <option data-bind="value: $data"></option>
                        </datalist>
                    </div>

管辖权
logChange方法被调用,但它看起来不像rateLimit被应用,因为logChange在按键时立即被调用

更新:

我已经更新了下面的小提琴。您所犯的错误是,您在更新新值之后立即调用了logChange函数中的函数。但rateLimit的概念是,可观测值发生更改的通知在延迟后发送给其所有订户

换句话说,只有被观察者的订阅者受到rateLimit的影响,而不是logChange函数中的任何内容。因此,正确的方法是在订阅服务器中调用autoSave函数

函数ViewModel(){
var self=这个;
self.autoSave=函数(attName,value){
console.log(attName+”现在是=“+value”);
}
self.precision=ko.observable();
ko.extenders.logChange=函数(目标,精度){
//创建一个可写的计算可观察对象,以拦截对我们的可观察对象的写入
var结果=ko.pureComputed({
read:target,//始终返回原始可观察值
写入:函数(newValue){
var current=target(),
valueToWrite=newValue;//,
自身精度(精度);
//attName=精度;
//只有改变了才写
如果(valueToWrite!==当前){
目标(valueToWrite);
//autoSave(attName,target());
}否则{
//如果舍入值相同,但写入了不同的值,则强制为当前字段发出通知
如果(新值!==当前值){
target.notifySubscribers(valueToWrite);
}
}
}
}).extend({notify:'总是'});
//使用当前值初始化,以确保它已适当舍入
结果(target());
//返回新的计算可观察值
返回结果;
};
self.controlCenter=ko.observable().extend({rateLimit:{timeout:500,方法:“notifywhenchangestop”},日志更改:“controlCenter”});
自我控制中心=ko.observearray([]);
此.controlCenter.subscribe(功能(val){
如果(val!='')
这个.controlCenters.push(val);
autoSave(self.precision(),val);
},这个);
}
应用绑定(新的ViewModel())

管辖权

您从这里获得了代码,对吗?我接受了您的代码并添加了“loggedValues”代码,将其更改为您的controlCenters变量。它工作得很好,同时还有费率限制延迟。或者你是说它会立即进入调试器?是的,我就是从这个链接获得代码的。我在按键时立即点击logChange函数中的调试器,因此也会调用我的autosave函数get。因此,如果我输入值“DIABLO”作为控制中心,它将尝试保存“D”、“DI”、“DIA”等。我希望autosave在ratelimit之后调用。它确实在ratelimit之后被调用,即使它立即点击调试器。好的,我将发布我的代码,其中包括我猜测的代码的剩余部分,并减去调试器。试试看。我很感谢你的帮助,但是autosave函数仍然会立即被调用,它不会在速率限制后被调用。你能提供一把小提琴吗?我已经在小提琴上添加了自动保存功能。在我的代码中,我会将属性名称和值发布到服务器,但举例来说,它只是将属性和值记录到控制台。如果你打开控制台,你会看到在按键时写入的值,而不是在速率限制之后。更新了答案,还有我的小提琴