敲除验证订阅更改后更新
knockout validation subscribe update after change
我有模型 'search Parameters',它有两个属性 title 和 priceMax,两者都是必需的。当用户更改属性时,脚本会从 API 更新报价数量。当模型 'searchParameters' 没有错误时,执行更新。问题出在方法中,return 计算模型中的错误。当 title 和 priceMax 有值时,方法 return 错误,只有当我再次更改模型的 属性 方法 return 值 0 时。知道吗?这是我的解决方案。
HTML
<fieldset>
<div class="row">
<label>Title:</label>
<input type="text" data-bind="textInput: searchParameters.title" />
</div>
<div class="row">
<label>Price max:</label>
<input data-bind="textInput: searchParameters.priceMax" />
</div>
<div class="row">
<label>count offers:</label>
<span data-bind="text: countOffers"></span>
</div>
<div class="row" data-bind="visible:visibleProgress">
progress...
</div>
</fieldset>
JS
function ViewModel() {
var self = this;
self.countOffers = ko.observable(0);
self.visibleProgress = ko.observable(false);
ko.extenders.refreshCountOffers = function(target, timeout) {
var timerId = null;
target.subscribe(function(newValue) {
console.log(self.errors());
if (self.errors().length === 0) {
clearTimeout(timerId);
timerId = setTimeout(function() {
self.visibleProgress(true);
//mock api
$.ajax({
url: '/echo/js/?js=' + Math.floor((Math.random() * 100)),
data: {
delay: 2
},
complete: function(response) {
self.countOffers(response.responseText);
self.visibleProgress(false);
}
});
//mock api
}, 500);
} else
self.countOffers(0);
});
return target;
};
self.searchParameters = {
title: ko.observable().extend({
refreshCountOffers: 500
}).extend({
required: true
}),
priceMax: ko.observable().extend({
refreshCountOffers: 500
}).extend({
required: true
})
};
self.errors = ko.validation.group(self.searchParameters);
};
var model = new ViewModel();
ko.applyBindings(model);
我的jsfiddle
这是因为您应用增效剂的顺序。当你扩展一个 observable 时,每个扩展器都是 运行 在前一个扩展器的结果上串行。
因此,您的代码扩展了 原始 可观察对象(它订阅更改的地方),然后再次扩展可观察对象以使其成为必需的。
老实说,我不是 100% 确定 knockout-validation
对导致您看到的行为的源可观察对象做了什么,但是如果您颠倒扩展程序的顺序(如 this jsFiddle ) 然后你保证你的自定义扩展器将在 'final' observable 上运行,因此将按你期望的那样工作。
self.user = {
firstName: ko.observable().extend({
required: true,
refreshCountOffers: 500
}),
lastName: ko.observable().extend({
required: true,
refreshCountOffers: 500
})
};
我有模型 'search Parameters',它有两个属性 title 和 priceMax,两者都是必需的。当用户更改属性时,脚本会从 API 更新报价数量。当模型 'searchParameters' 没有错误时,执行更新。问题出在方法中,return 计算模型中的错误。当 title 和 priceMax 有值时,方法 return 错误,只有当我再次更改模型的 属性 方法 return 值 0 时。知道吗?这是我的解决方案。
HTML
<fieldset>
<div class="row">
<label>Title:</label>
<input type="text" data-bind="textInput: searchParameters.title" />
</div>
<div class="row">
<label>Price max:</label>
<input data-bind="textInput: searchParameters.priceMax" />
</div>
<div class="row">
<label>count offers:</label>
<span data-bind="text: countOffers"></span>
</div>
<div class="row" data-bind="visible:visibleProgress">
progress...
</div>
</fieldset>
JS
function ViewModel() {
var self = this;
self.countOffers = ko.observable(0);
self.visibleProgress = ko.observable(false);
ko.extenders.refreshCountOffers = function(target, timeout) {
var timerId = null;
target.subscribe(function(newValue) {
console.log(self.errors());
if (self.errors().length === 0) {
clearTimeout(timerId);
timerId = setTimeout(function() {
self.visibleProgress(true);
//mock api
$.ajax({
url: '/echo/js/?js=' + Math.floor((Math.random() * 100)),
data: {
delay: 2
},
complete: function(response) {
self.countOffers(response.responseText);
self.visibleProgress(false);
}
});
//mock api
}, 500);
} else
self.countOffers(0);
});
return target;
};
self.searchParameters = {
title: ko.observable().extend({
refreshCountOffers: 500
}).extend({
required: true
}),
priceMax: ko.observable().extend({
refreshCountOffers: 500
}).extend({
required: true
})
};
self.errors = ko.validation.group(self.searchParameters);
};
var model = new ViewModel();
ko.applyBindings(model);
我的jsfiddle
这是因为您应用增效剂的顺序。当你扩展一个 observable 时,每个扩展器都是 运行 在前一个扩展器的结果上串行。
因此,您的代码扩展了 原始 可观察对象(它订阅更改的地方),然后再次扩展可观察对象以使其成为必需的。
老实说,我不是 100% 确定 knockout-validation
对导致您看到的行为的源可观察对象做了什么,但是如果您颠倒扩展程序的顺序(如 this jsFiddle ) 然后你保证你的自定义扩展器将在 'final' observable 上运行,因此将按你期望的那样工作。
self.user = {
firstName: ko.observable().extend({
required: true,
refreshCountOffers: 500
}),
lastName: ko.observable().extend({
required: true,
refreshCountOffers: 500
})
};