gpt4 book ai didi

javascript - 超时后调用 Knockout JS Extender 函数

转载 作者:行者123 更新时间:2023-11-30 21:07:35 25 4
gpt4 key购买 nike

我目前正在尝试使用扩展程序在 Knockout JS 应用程序中实现自动保存功能。我想在用户停止在字段中输入时调用自动保存功能,而不仅仅是当他们退出时。

这是我想在更新可观察对象时调用的 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;

};

这就是我在我的 View 模型中设置可观察对象的方式。

    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。

最佳答案

更新:

我已经更新了下面的 fiddle 。您犯的错误是您在更新新值后立即调用 logChange 函数内的函数。但 rateLimit 的概念是,可观察值已更改的通知在延迟后发送给所有订阅者。

换句话说,只有 observable 的订阅者会受到 rateLimit 的影响,而不会影响 logChange 函数中的任何内容。因此,正确的做法是在订阅者内部调用您的自动保存功能。

function ViewModel() {
var self = this;
self.autoSave = function(attName, value){
console.log(attName + " is now = " + value);
}
self.precision = ko.observable();
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) {

var current = target(),
valueToWrite = newValue;//,
self.precision(precision);
//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;

};

self.controlCenter = ko.observable().extend({ rateLimit: { timeout: 500, method: "notifyWhenChangesStop" }, logChange: "ControlCenter" });
self.controlCenters = ko.observableArray([]);
this.controlCenter.subscribe(function (val) {
if (val !== '')
this.controlCenters.push(val);
self.autoSave(self.precision(), val);
}, this);
}


ko.applyBindings(new ViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<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>

关于javascript - 超时后调用 Knockout JS Extender 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46474787/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com