5

我目前使用 Jquery Validation 和 Qtip 一起使用验证选项的 errorPlacement 组件在验证错误时使用漂亮的工具提示样式通知来处理实际验证和信息显示到屏幕。

目前,每个 viewModel 都有自己的自定义方法来设置和启动验证和回调,但是我试图寻找一种更好的方法,无论是添加自定义绑定来通过数据绑定设置我的验证规则还是另一种方法,但仍然产生相同的结果(即当发生验证错误时触发 errorPlacement 并告诉 Qtip 显示给定元素的错误)。

现在,在我开始自己制作之前,我刚刚在网上查了一下,发现了Knockout Validation,我最初认为这是一个好主意,我可以将我的验证逻辑直接应用于我的 viewModel 中的数据,然后找到某种回调来让 Qtip 使用开始,但是似乎没有我可以找到记录的回调。该库似乎为事物的验证方面做了我想做的一切,而不是为事物的显示方面。我查看了源代码和示例,但除了 ko.validation.group(viewModel) 之外什么都看不到,这会给我一个包含错误的 observable,但我不确定我是否可以像以前一样使用它期待。

这是我当前验证如何发生的示例:

/*globals $ ko */
function SomeViewModel() {

    this.SetupValidation = function () {
        var formValidationOptions = {
            submitHandler: self.DoSomethingWhenValid,
            success: $.noop,
            errorPlacement: function (error, element) {
                if (!error.is(':empty'))
                { qtip.DoSomethingToDisplayValidationErrorForElement(element, error); }
                else
                { qtip.DoSomethingToHideValidationErrorForElement(element); }
            }
        };

        $(someForm).validate(formValidationOptions);
        this.SetupValidationRules();
    };

    this.SetupValidationRules = function() {
        $(someFormElement1).rules("add", { required: true, minlength: 6, maxlength: 20, alphaNumeric: true });
        $(someFormElement2).rules("add", { required: true, minlength: 6, maxlength: 20 });
        $(someFormElement3).rules("add", { required: true, email: true, });
    };
}

我目前确信我可以通过添加自定义绑定来消除对验证规则方法的需求,这样我就可以在数据绑定中设置验证,但是如果可能的话,我想使用与现有 Knockout 相同的回调方法-验证绑定。

4

2 回答 2

5

我没有专门使用 Knockout-Validation,但我过去写过类似的东西。快速浏览一下源代码就会发现,每个扩展的 observable 都有一个sub-observable isValid。这可用于使用传统的剔除可见绑定隐藏标记中的显示消息。

要让 QTip 工作,自定义绑定可以订阅此 isValid 属性并执行必要的初始化以在触发时显示/隐藏 QTip。

编辑

这是一个让您入门的示例

http://jsfiddle.net/madcapnmckay/hfcj7/

HTML:

<!-- Note that you have to reference the "qtipValMessage" binding -->
<!-- using the "value" binding alone is not enough                -->
<input data-bind="value: emailAddress, qtipValMessage : emailAddress" />

JS:

ko.bindingHandlers.qtipValMessage = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
        var observable = valueAccessor(), $element = $(element);
       if (observable.isValid) {
            observable.isValid.subscribe(function(valid) {
                if (!valid) {
                    $element.qtip({
                        overwrite: true,
                        content: {
                            text: observable.error
                        }
                     });
                 } else {
                     $element.qtip("destroy");
                 }
           });
       }
    }
};
于 2012-02-24T17:42:09.710 回答
1

我一直在编辑 madcapnmckay 的帖子,但差异已经变得足够大,以至于我认为需要一个新的答案。

它很大程度上基于 madcapnmckay 的帖子,但它修复了 MorganTiley 指出的错误。原始版本仅在用户修改了 observable 时才有效。如果他们没有,那么代码永远不会被解雇。因此,我对其进行了修改,以便它在创建时触发工具提示代码,以及在它更改时。

ko.bindingHandlers.qtipValMessage = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
        var observable = valueAccessor(), $element = $(element);
        if (observable.isValid) {
            var updateTooltip = function (valid) {
                if (!valid) {
                    $element.qtip({
                        overwrite: true,
                        content: {
                            text: observable.error
                        }
                    });
                } else {
                    $element.qtip("destroy");
                }
            }
            updateTooltip();
            observable.isValid.subscribe(updateTooltip);
        }
    }
};

一个缺点是在敲除验证运行之前,工具提示将在悬停时显示(例如,您对字段进行了“必需”验证,在您按下提交之前,工具提示将显示该字段是必需的,但该字段不会以粉红色突出显示)。但是,一旦您更改了该字段,如果该字段有效,则工具提示将消失。

我的应用程序没有使用 qtip,而是使用 Twitter Bootstrap Tooltip,所以这里也是它的代码。

ko.bindingHandlers.invalidTooltip = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
        var observable = valueAccessor(), $element = $(element);
        if (observable.isValid) {
            var updateTooltip = function (valid) {
                if (!valid) {
                    $element.attr("data-original-title", observable.error);
                    $element.tooltip();

                } else {
                    $element.tooltip("destroy");
                }
            }
            updateTooltip();
            observable.isValid.subscribe(updateTooltip);
        }
    }
};
于 2013-03-12T21:55:35.980 回答