Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/73.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Knockoutjs可观察订阅(循环)-防止用户输入错误的输入_Javascript_Jquery_Knockout.js - Fatal编程技术网

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

Javascript Knockoutjs可观察订阅(循环)-防止用户输入错误的输入,javascript,jquery,knockout.js,Javascript,Jquery,Knockout.js,如果用户输入不是预期值,是否可以不更改值?例如,以下代码起作用: 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){

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

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

但是,通过调试,我意识到当我使用this.expthis.previousValue更改可观察变量exp的值时;再次触发订阅,并重复几次,直到值与beforeChange和change事件相同。是否有一种绕过这种重复的解决方法?

我采用的方法是使用自定义绑定和订阅。此解决方案使用了来自此问题/答案的想法:

我在这里创建了一个新小提琴:

下面是从小提琴上摘录的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" />
仍然存在一个循环,虽然它只有两次,比以前少了很多,但是仍然存在一个循环,我假设这是因为exp中的更改传播回了计算结果。这可以避免吗?奇怪,我没有看到这种行为。也许你可以发布一个JSFIDLE?每次用户更新字段时,我都会看到一次写更新,而不是当可计算表更新基础的可观察对象时。看到这把小提琴:我更新了你的解决方案,正如你所看到的,我期望的是,当我将值更改为错误值时,文本框expComputed应该保留该值,当我强制它时,拍摄计算的可观察对象的订阅,然后循环。@Lordbalmon我创建了一个新的小提琴,并更改了答案以解决您的问题。任何无效值都将被还原。。。该解决方案甚至在JSFIDLE上也不起作用,顺便说一句,我接受了你的解决方案,因为它是最好的:,谢谢。