【问题标题】:Comparing two fields with knockout-validation比较两个字段与淘汰赛验证
【发布时间】:2013-01-12 23:55:03
【问题描述】:

我有一个表单的视图模型,我正在尝试将验证添加到使用敲除验证。

fromDate: ko.observable(
            moment().subtract('days', 1).startOf('day').format(dateFormat)
          ),
toDate: ko.observable(
            moment().startOf('day').format(dateFormat)
        ),

我需要确保起始日期小于截止日期。我似乎无法获得任何形式的自定义验证器来获取对第二个 observable 的引用。我需要一些类似的东西:

toDate: ko.observable(moment().startOf('day').format(dateFormat)).extend({
          validation: {
            validator: function (val, someOtherVal) {
                return moment(val) >= moment(someOtherVal);
            },
            message: 'Must be greater or equal to From Date',
            params: viewModel.fromDate()
          }
        }),

有什么想法吗?

更新

我确定我已经尝试过了,但是将扩展方法移到 onload 函数中是可行的。

$(function () {
    ko.validation.configure({ decorateElement: true });

    viewModel.toDate.extend({
    validation: {
            validator: function (val, someOtherVal) {
                return moment(val) >= moment(viewModel.fromDate());
            },
            message: 'To date must be greater than from date',
        }
    });

    ko.applyBindings(viewModel);
});

【问题讨论】:

    标签: knockout.js knockout-validation


    【解决方案1】:

    knockout-validation 的核心规则不能将 observables 处理为验证参数。但是已经有一个推送请求可以解决这个问题:https://github.com/ericmbarnard/Knockout-Validation/pull/217

    因此,您必须为此使用自定义角色。您应该将参数作为函数插入(通过省略括号)。这将使淘汰赛验证能够对参数的变化做出反应。

    function ViewModel() {
        var self = this; // capture this to be able to reference properties
    
        self.fromDate = ko.observable(
            moment().subtract('days', 1).startOf('day').format(dateFormat)
        );
        self.toDate = ko.observable(
            moment().startOf('day').format(dateFormat)
        ).extend({
          validation: {
            validator: function (val, someOtherVal) {
                return moment(val) >= moment(someOtherVal());
            },
            message: 'Must be greater or equal to From Date',
            params: self.fromDate
          }
        }),
    }
    

    【讨论】:

      【解决方案2】:

      看看documentation,这看起来像你可以做到的方式:

      ko.validation.rules['greaterThan'] = {
          validator: function (val, otherVal) {
              return val > otherVal;
          },
          message: 'The field must be greater than {0}'
      };
      
      ko.validation.registerExtenders();
      
      fromDate: ko.observable(
                  moment().subtract('days', 1).startOf('day').format(dateFormat)
                ),
      toDate: ko.observable(
                  moment().startOf('day').format(dateFormat)
              ).extend({ greaterThan: fromDate() });
      

      未经测试,不知道你是要传入fromDate(),还是fromDate,然后在验证器中使用otherVal()。

      【讨论】:

      • 已经试过了,还是会出现'Uncaught TypeError: Cannot call method 'fromDate' of undefined'
      • 您在视图模型中是否有参考(var self = this),并尝试使用greaterThan: self.fromDate()?
      • 是的,如果扩展方法在视图模型内部声明,它们似乎无法引用视图模型。一旦有视图模型的实例就注册它们似乎有效。请注意,我使用的是 var vm ={} 语法而不是基于函数的语法,那么情况可能并非如此。
      • 我想这是因为在您添加扩展方法时,视图模型尚未完成初始化,因此它不存在,因此在您的验证方法中未定义。跨度>
      • 保罗回答的最后一行应该是这样的: ).extend({ greaterThan: this.fromDate });即参数必须不带括号传递。第三行应该是这样的:return val > otherVal(); -- 带括号的 otherVal。这样就可以了。
      【解决方案3】:

      这有点晚了,但是当我在谷歌上搜索“knockoutjs 密码字段匹配”时,这是最热门的。

      我想要一个不使用验证扩展的匹配器,因为我不需要该包的所有产品。

      我发现了一个整洁的 knockoutjs 技巧,用于使用扩展器检查两个或多个字段。也就是说,将原始字段订阅到扩展程序中的第二个字段,以便在更新原始字段时针对第二个字段触发 valueHasMutated()。

        ko.extenders.match = function(target, match_original) {
        target.match_ok = ko.observable();
        function copy(value) {
          target.match_ok(value == match_original());
        }
        function original(value) {
          target.valueHasMutated();
        }
        copy(target());
        target.subscribe(copy);
        match_original.subscribe(original);
        return target;
      };
      

      这是一个 jsfiddle 以更好地说明功能 https://jsfiddle.net/8nugva9f/13/

      HTH

      【讨论】:

        【解决方案4】:
        this.fromDate= ko.observable(null).extend({
                date: true,
        
            });
        
        this.toDate = ko.observable(null).extend({
                date: true,
                min: this.fromDate,
        
            });
        

        试试这个。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-12-29
          • 2012-02-18
          • 2012-10-14
          • 1970-01-01
          • 2014-02-01
          • 2011-08-09
          • 2014-10-13
          • 2015-10-18
          相关资源
          最近更新 更多