可观察订阅(循环)-防止用户输入错误的输入

Knockoutjs Observable Subscription (loop) - Prevent user from entering wrong input

本文关键字:输入 用户 错误 观察 循环      更新时间:2023-09-26

如果用户输入不是预期的值,是否可能"不更改"值?例如,下面的代码可以工作:

function data(sno, exp) {
        var self = this;
        self.sno = ko.observable(sno);
        self.exp = ko.observable(exp);
        self.previousValue = 0;
        self.exp.subscribe(function(param1){
            this.previousValue = param1;
        }, self, "beforeChange");
        self.exp.subscribe(function(param1){
            try {
                this.exp(eval(param1));
            }
            catch(err) {
                this.exp(this.previousValue);
            }
        }, self);
    }

但是,调试时我意识到,当我改变可观察变量exp的值时,使用this.exp(this.previousValue);再次触发订阅,这重复了几次,直到值与beforeChangechange事件没有不同。是否存在绕过这种重复的方法?

我采用的方法是使用自定义绑定和订阅。这个解决方案使用了一个想法,从这个问题/答案在这里:如何定义一个自定义绑定谁使用以前的值来确定类在Knockout?

我在这里创建了一个新的提琴:http://jsfiddle.net/joshnicholson/F4bds/1

这是小提琴的Javascript摘录。最好访问链接查看完整示例:

function subscribeToPreviousValue(observable, fn) {
    observable.subscribe(fn, this, 'beforeChange');
}
function isInvalid(expression) {
    return expression === 'invalid';
}
function data(sno, exp) {
    var self = this;
    self.sno = ko.observable(sno);
    self.exp = ko.observable(exp).extend({throttle: 200});
    self.writeCount = ko.observable(0);
    self.output = ko.observable("");    
    self.log = function(msg) {
        var content = self.output();
        self.output(content + "> " + msg + "<br />");
    };
}
ko.bindingHandlers.bindingWithPrevValue = {
    init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
        var vm = bindingContext.$data,
            observable = valueAccessor(),
            current = observable();
        vm.log('Initial value is ' + current);
        subscribeToPreviousValue(observable, function (previous) {
            var newValue = element.value; 
            if(isInvalid(previous)) return;
            vm.log('');
            vm.log('value changed from ' + previous + ' to ' + newValue);            
            if(isInvalid(newValue)) {
                vm.log(newValue + ' is not valid. reverting...');
                observable(previous);
            }
        });
    }
};
ko.applyBindings(new data("000-11-2222", "testexp"));

在HTML中:

  input type="text" data-bind="value: exp, bindingWithPrevValue: exp"/>