更改另一个计算的可观察值时触发一个可观察值的自定义扩展程序

拉姆基

我正在尝试创建自己的验证,而无需使用敲除验证库。我正在尝试创建一个通用的Validate扩展程序,该扩展程序可以执行我想要执行的所有类型的验证。通过将验证类型和对象中的必需标志传递给扩展程序来实现此目的。问题在于,仅当Password字段更改时,validate方法才会触发,而PasswordVisible属性更改时,则不会触发validate方法。当密码已经为空并且更改了PasswordVisible属性时,这会导致问题,将清空密码的尝试不视为更改,因此不会触发扩展程序。

<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    <script type="text/javascript" src="knockout-3.4.0.js"></script>

    Name:<input type="text" data-bind="value:Name" /><br />
    Already A User: <input type="checkbox" data-bind="checked:AlreadyUser" /><br />
    New Password:<input type="password" data-bind="value:Password,visible:PasswordVisible" /><br />
    <input type="button" value="Submit" onclick="validateModel();" />

    <script type="text/javascript" >
        var pageModel;

        ko.extenders.Validate = function (target, validateOptions) {
            target.HasErrors = ko.observable(false);
            var required = validateOptions.required();
            var validationType = validateOptions.validationType;
            function validate(newValue) {
                alert('validating');
                if (required) {
                    switch (validationType) {
                        case "Text":
                            target.HasErrors(newValue == "" ? false : true);
                            break;
                        default:
                            target.HasErrors(false);
                            break;
                    }
                }
            }

            validate(target());
            target.subscribe(validate);
            return target;
        };

        //The model itself
        var ViewModel = function () {            
            var self = this;
            self.Name = ko.observable('');
            self.AlreadyUser = ko.observable(false);
            //computed variable that sets the visibility of the password field. I have to clear the password when am making it invisible
            self.PasswordVisible = ko.computed(function () { return !this.AlreadyUser(); }, this).extend({ notify: 'always' });
            //this field is only required when visible
            self.Password = ko.observable('').extend({ Validate: { required: function () { return self.PasswordVisible() }, validationType: "Text" } });
            self.PasswordVisible.subscribe(function (newVal) { self.Password(''); });
            self.HasErrors = ko.computed(function () { return self.Password.HasErrors(); },self);
        };



        //The method calls on click of button
        function validateModel() {
            alert(pageModel.HasErrors());
            }

        //create new instance of model and bind to the page
        window.onload = function () {          
            pageModel = new ViewModel();
            ko.applyBindings(pageModel);
        };

    </script>
</body>
</html>

更改PasswordVisible时如何触发验证。

用户名

您可以创建HasErrors一个ko.computed自动创建对任何可观察到的订阅的订阅。不过,它可能会触发一些不必要的重新评估...

ko.extenders.Validate = function(target, validateOptions) {
  target.HasErrors = ko.computed(function() {
    // Create subscription to newValue
    var newValue = target();

    // Create subscriptions to any obs. used in required
    var required = validateOptions.required();
    var validationType = validateOptions.validationType;

    if (ko.unwrap(required)) {
      switch (validationType) {
        case "Text":
          return newValue == "";
      }
    };


    return false;
  }, null, {
    deferEvaluation: true
  });

  return target;
};

注意,您也不需要将PasswordVisibleobservable包装在函数中即可执行;您可以ko.unwrap改用。

这是我在您的代码中使用的方法。当您在内部有一个值的情况下隐藏了密码时,您可能想再看一次多次验证(clear viaself.Password('')触发另一个验证)。

var pageModel;
var i = 0;
ko.extenders.Validate = function(target, validateOptions) {
  target.HasErrors = ko.computed(function() {
    console.log("validating " + ++i);

    // Create subscription to newValue
    var newValue = target();

    // Create subscriptions to any obs. used in required
    var required = validateOptions.required();
    var validationType = validateOptions.validationType;

    if (ko.unwrap(required)) {
      switch (validationType) {
        case "Text":
          return newValue == "";
      }
    };


    return false;
  }, null, {
    deferEvaluation: true
  });

  return target;
};

//The model itself
var ViewModel = function() {
  var self = this;
  self.Name = ko.observable('');
  self.AlreadyUser = ko.observable(false);
  //computed variable that sets the visibility of the password field. I have to clear the password when am making it invisible
  self.PasswordVisible = ko.computed(function() {
    return !this.AlreadyUser();
  }, this).extend({
    notify: 'always'
  });
  //this field is only required when visible
  self.Password = ko.observable('').extend({
    Validate: {
      required: function() {
        return self.PasswordVisible()
      },
      validationType: "Text"
    }
  });
  self.PasswordVisible.subscribe(function(newVal) {
    self.Password('');
  });
  self.HasErrors = ko.computed(function() {
    return self.Password.HasErrors();
  }, self);
};



//The method calls on click of button
function validateModel() {
  console.log(pageModel.HasErrors());
}

//create new instance of model and bind to the page
window.onload = function() {
  pageModel = new ViewModel();
  ko.applyBindings(pageModel);
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

Name:
<input type="text" data-bind="value:Name" />
<br />Already A User:
<input type="checkbox" data-bind="checked:AlreadyUser" />
<br />New Password:
<input type="password" data-bind="value:Password,visible:PasswordVisible" />
<br />
<input type="button" value="Submit" onclick="validateModel();" />

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

根据另一个可观察值的值延迟发射可观察值

当另一个可观察值产生任何值时,选择可观察的最新值

RxJs:使用发射另一个可观察值来过滤可观察内容

MobX:如何根据另一个值的更改来更改可观察值?

如何使用一个可观察的状态跳过另一个可观察的值?

当另一个发出值时,可观察到RxJS错误

如何在另一个中使用一个可观察值?

当事件在另一个可观察者中发生时,从一个可观察者中检索值

使用一个可观察对象同步另一个可观察对象

用另一个可观察对象更改一个可观察对象的订阅状态

缓冲并减少值,同时切换到另一个可观察的值

使用来自一个可观察值的数据,然后将结果作为另一个可观察值返回

rxjs:如何从catchError的另一个可观察值返回结果

RxJS:为另一个可观察对象设置默认值

节流/缓冲基于Reactive Extensions中另一个观测值的可观察集合

订阅另一个可观察的订阅者?

另一个rxjs可观察的重试策略

如何用另一个可观察对象填充可观察对象并返回可观察对象

订阅另一个可观察对象内的嵌套可观察对象

将RxSwift可观察结果绑定到另一个可观察结果

RxSwift:将可观察的延迟到另一个可观察的完成之前?

当另一个可观察的变化时,如何调用可观察的Angular HttpClient?

角度6:将可观察的响应传递给另一个可观察的

检索可观察的订户并使他们订阅另一个可观察的订户

从另一个可观察对象调用可观察对象

RXAndroid:可观察等待另一个可观察完成

从多个可观察值创建一个可观察值

如何获得可观察关系链中第一个可观察值的值

使用RxJS如何触发另一个动作流的可观察对象