如何将淘汰赛验证附加到自定义绑定

Posted

技术标签:

【中文标题】如何将淘汰赛验证附加到自定义绑定【英文标题】:How To Attach Knockout Validation To A Custom Binding 【发布时间】:2015-06-25 00:01:17 【问题描述】:

我创建了一个 Knockout 自定义绑定来使用 moment.js 格式化日期。

ko.bindingHandlers.dateStringValue = 
    update: function (element, valueAccessor, allBindingsAccessor, viewModel) 
        var value = valueAccessor(),
        allBindings = allBindingsAccessor();
        var valueUnwrapped = ko.utils.unwrapObservable(value);

        if (valueUnwrapped === null) 
            ko.bindingHandlers.value.update(element, valueAccessor, allBindingsAccessor, viewModel);
            $(element).val("");
         else 
            ko.bindingHandlers.value.update(element, valueAccessor, allBindingsAccessor, viewModel);
            var pattern = allBindings.datePattern || "MM/DD/YYYY";
            $(element).val(moment(valueUnwrapped).format(pattern));
        
    
;

这对我的绑定很有效:

<input type="text" data-bind="dateStringValue: entryDate, datePattern: 'M/D/YYYY'" />

我从网上找到的代码创建了一个自定义验证规则。

// http://***.com/a/23086828/139917
// Use: var someDate= ko.observable().extend( simpleDate: true );
// Dependencies: date.js
ko.validation.rules['simpleDate'] = 
    validator: function (val, validate) 
        var d = Date.parse(val);
        return (d != null);
        //return ko.validation.utils.isEmptyVal(val) || moment(val, 'MM/DD/YYYY').isValid();
    ,
    message: 'Invalid date entry date'
;

ko.validation.registerExtenders();

我尝试了 moment.js 和 date.js 日期库。

我将自定义验证规则附加到我的 viewmodel observable。

self.entryDate = ko.observable(je.entryDate || new Date()).extend( simpleDate: true );

现在我想使用 Knockout Validation 来验证输入,但不知道如何让验证框架知道我的新绑定。似乎 Knockout Validation 只知道部分或全部内置的 Knockout 绑定。​​

在 Knockout v3.2.0 中调用 ko.validation.makeBindingHandlerValidatable("dateStringValue"); 会引发 0x800a138f - javascript runtime error: Object expected 错误。有人建议从我的自定义绑定中调用 Knockout 值绑定可以工作,但像 ko.bindingHandlers.value.update(element, valueAccessor); 这样的代码对我不起作用。

如何让 Knockout Validation 知道我的自定义绑定?

【问题讨论】:

【参考方案1】:

通过将新参数传递给绑定,即在自定义绑定中创建验证,即:

<input type="text" data-bind="customDate:  value: entryDate, pattern: 'M/D/YYYY'", validatable: true  />

只需在绑定中施展魔法即可。

【讨论】:

如果输入的值验证失败会怎样?我可以点击敲除验证以显示错误标签吗?如何将其添加到调用 var errors = ko.validation.group(selectedEntry, deep: false ); 时创建的错误数组中?【参考方案2】:

这是我解决问题的方法。我在我的实体上创建了一个读/写计算属性,并使用 moment.js 来验证输入:

var dateFormatString = "M/D/YYYY"

self.entryDate = ko.observable(je.entryDate || new Date());
self.formattedEntryDate = ko.computed(
    read: function () 
        return moment(self.entryDate()).format(dateFormatString);
    ,
    write: function (value) 
        var momentDate = moment(value, dateFormatString);
        if (momentDate.isValid()) 
            self.entryDate(momentDate.format(dateFormatString));
            self.isValidEntryDate(true);
            return;
        
        self.isValidEntryDate(false);
    ,
    owner: self
);
self.isValidEntryDate = ko.observable(true);

如果输入字符串不是预期的格式,我会将 isValidEntryDate observable 设置为 false,这将向用户显示一条消息,提示他们重新输入日期。

<input type="text" data-bind="value: formattedEntryDate" />
<div class="validationMessage" data-bind="hidden: isValidEntryDate">Invalid entry date. Use M/D/YYYY format.</div>

此绑定使用hidden 的自定义绑定处理程序。

我意识到这并没有解决问题,但以生产力的名义,这实现了目标。

欢迎直接回答问题。

【讨论】:

【参考方案3】:

我得到它的工作如下 -

<input type="text" data-bind="dateStringValue: entryDate.extend( simpleDate: entryDate()), datePattern: 'M/D/YYYY'" />

【讨论】:

以上是关于如何将淘汰赛验证附加到自定义绑定的主要内容,如果未能解决你的问题,请参考以下文章

RxSwift 不将数据绑定到自定义集合视图单元格

将 TableView 中的 CheckBox 选中状态绑定到自定义模型属性

xcode - 将 xib 文件附加到自定义 UIView 类时出错

将 ngModel 绑定到自定义指令

如何添加 onCommit、isEditing 以及自定义绑定到自定义 textview 的能力?

将单击操作绑定到自定义 xaml 组件