简体   繁体   English

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

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

Is it possible to "not change" a value if the user input is not what was expected? 如果用户输入不是期望的值,是否可以“不更改”值? For example, the below code works: 例如,以下代码有效:

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);
    }

But, debugging this I realized that the when I change the value of the observable variable, exp , using this.exp(this.previousValue); 但是,调试它时,我意识到,当我使用this.exp(this.previousValue);更改可观察变量exp triggers the subscription again and this repeats a few times till the value is not different from beforeChange and change events. 再次触发订阅,并重复几次,直到该值与beforeChangechange事件相同。 Is there a workaround to bypass this repetition? 有没有解决方法可以绕过此重复?

The approach I followed used a custom binding and a subscription. 我遵循的方法使用了自定义绑定和订阅。 This solution uses an idea from this SO question/answer here: How to define a custom binding who use previous value to determine class in Knockout? 此解决方案使用此处的SO问题/答案中的一个想法: 如何定义使用先前值确定Knockout中的类的自定义绑定?

I've created a new Fiddle here: http://jsfiddle.net/joshnicholson/F4bds/1 我在这里创建了一个新的小提琴: http : //jsfiddle.net/joshnicholson/F4bds/1

Here is the Javascript excerpt from the Fiddle. 这是Fiddle的Javascript摘录。 It's best to visit the link to see the full example: 最好访问链接以查看完整的示例:

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"));

And in the HTML: 在HTML中:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM