如何在Knockout验证中使用正反馈验证

时间:2016-06-21 15:05:16

标签: javascript jquery validation knockout.js

我需要一些关于Knockout验证的积极反馈。定期Knockout验证使用data-bind =“validationElement”。有点像这样:

<div data-bind="validationElement: path.to.ko.property">
    <input type="text" data-bind="value: path.to.ko.property />
</div>

验证错误可以这样显示,有两种不同的方法(参见:https://github.com/Knockout-Contrib/Knockout-Validation/wiki/Validation-Bindings):

<div data-bind="validationElement: path.to.ko.property">
     some html/text which will be shown when there is an error.
</div>
<div data-bind="validationMessage: path.to.ko.property">
     some html/text which will be shown when there is an error.
</div>

我想要的也是积极反馈。因此,当字段正确填充(验证通过)时,我希望向用户显示正面反馈。

1 个答案:

答案 0 :(得分:0)

搜索后,我发现了一些代码片段,但实际上没有任何工作。所以在我找到自己的解决方案之后。我在这里分享它,所以其他人可能遇到同样的问题,并希望使用相同的方法。

你基本上只需要一个额外的绑定处理程序来完成这项工作。您可以使用新的bindingHandler,但我所做的是覆盖并扩展现有的:[/ p>

/**
 * Custom binding for adding an extra success class to the element when success.
 * OVERRIDE NOTE!! use the original for validation first.
 * @type {{update: ko.bindingHandlers.validationElement.update}}
 */
var originalBindingHandlerValidationElement = ko.bindingHandlers.validationElement;

ko.bindingHandlers.validationElement = {
    update: function (element, valueAccessor, allBindingsAccessor) {
        // call original method.
        originalBindingHandlerValidationElement.update(element, valueAccessor, allBindingsAccessor);

        var obsv = valueAccessor(),
            isModified = false,
            isValid = false,
            isValidating = false;

        if (obsv === null || typeof obsv === 'undefined') {
            throw new Error('Cannot bind validationElement to undefined value. data-bind expression: ' +
                element.getAttribute('data-bind'));
        }

        isValid = obsv.isValid && obsv.isValid();
        isModified = obsv.isModified && obsv.isModified();
        isValidating = obsv.isValidating && obsv.isValidating();

        // create an evaluator function that will return something like:
        // css: { validationElement: true }
        var cssSettingsAccessor = function () {
            var css = {};

            css["has-success"] = isValid && (isModified && (obsv()!==null));
            css["has-progress"] = isModified && isValidating;

            return css;
        };

        //add or remove class on the element;
        ko.bindingHandlers.css.update(element, cssSettingsAccessor, allBindingsAccessor);
    }
};

我正在使用原始的bindingHandler来处理已经使用Knockout Validation插件的错误状态。但是当元素成功或正在处理时,为元素添加了“has-success”和“has-progress”类。我正在使用的淘汰验证初始化是:

    ko.validation.init({
        insertMessages: false,
        errorClass: 'has-error',
        errorsAsTitle: false,
        grouping: {
            observable: true,
            deep: true
        }
    }, true);

这导致将放置3个类:has-success,has-error,has-progress。

下一步是让我在多个字段一起有效或无效时获得某种汇总反馈。所以我做了另一个bindingHandler:

/**
 * Custom binding for multiple checked properties to validate
 * Usage example: validationElements:[path.to.prop1,path.to.prop2]
 * @type {{update: ko.bindingHandlers.validationElements.update}}
 */
ko.bindingHandlers.validationElements = {
    update: function (element, valueAccessor, allBindingsAccessor,vm) {
        var properties = valueAccessor();
        var allValid = true, allValidating = true, allModified = true, allNull = true;

        for(var i=0;i<properties.length;i++) {
            var propModel = properties[i];

            var isModified = propModel.isModified && propModel.isModified(),
                isValid = propModel.isValid && propModel.isValid(),
                isValidating = propModel.isValidating && propModel.isValidating();

            allValid = allValid && isValid;
            allModified = allModified && isModified;
            allValidating = allValidating && isValidating;
            allNull = allNull && (propModel()!==null);
        }

        // create an evaluator function that will return something like:
        // css: { validationElement: true }
        var cssSettingsAccessor = function () {
            var css = {};

            css["has-success"] = allValid;
            css["has-progress"] = allModified && allValidating;
            css["has-error"] = !allValid && allModified;

            return css;
        };

        //add or remove class on the element;
        ko.bindingHandlers.css.update(element, cssSettingsAccessor, allBindingsAccessor);
    }
};

此验证处理程序可以像这样使用:

<div data-bind="validationElement: path.to.ko.property1">
    <input type="text" data-bind="value: path.to.ko.property1" />
</div>
<div data-bind="validationElement: path.to.ko.property2">
    <input type="text" data-bind="value: path.to.ko.property2" />
</div>
<div data-bind="validationElements:[path.to.ko.property1, path.to.ko.property2]">
     <i class="fa fa-check is-success"></i>
     <i class="fa fa-exclamation-circle is-error"></i>
     <i class="fa fa-spinner fa-pulse is-progress"></i>
</div>

在验证之后/验证期间,validationElements div将变为以下之一:                                         要么                                         要么                                        

通过这种方法,您可以为用户提供有关验证的正面反馈。使用以下css片段,你可以指出它。

.is-success,
.is-error,
.is-progress {
    display: none;
}
.has-success .is-success {
    color: green;
    display: block;
}
.has-error .is-error {
    color: red;
    display: block;
}
.has-progress .is-progress {
    color: yellow;
    display: block;
}

我希望这会对其他人有所帮助,因为我需要花费几个小时才能完成它。我用最小的工作示例设置了一个codepen:http://codepen.io/anon/pen/ZOBbJG