knockout-validation:绑定到validationMessage更改

时间:2013-11-04 02:02:02

标签: knockout.js knockout-validation

我正在使用一个使用敲除验证的表单,并且我有一个confirmPassword输入,该输入与显示验证消息的span相关联(即我在ko.validation.init中将insertMessages设置为false)。我希望在这个范围内有一个滑入式动画,所以它包含在一个div中,它有一个自定义绑定来改变高度(我在高度上设置了css过渡):

<div class="slideOuter">
    <div class="slideInner" data-bind="slideElement: confirmPassword.isModified() & !confirmPassword.isValid()">
        ...
        <span class="form-control" data-bind="validationMessage: confirmPassword"></span>
        ...

绑定代码:

ko.bindingHandlers.slideElement = {
    update: function (element, valueAccessor, allBindings) {
        // First get the latest data that we're bound to
        var value = valueAccessor();

        // Next, whether or not the supplied model property is observable, get its current value
        var valueUnwrapped = ko.unwrap(value);

        var $outer = $(element).closest('.slideOuter');
        var $inner = $(element).closest('.slideInner');

        if (valueUnwrapped == true) {
            // Make the element visible
            $(element).css('display', 'block');
            setTimeout(function () { $outer.css('height', $inner.outerHeight(true) + "px"); }, 0);
        }
        else {
            // Make the element invisible
            $(element).css('display', 'none');
            $outer.css('height', "0px");
        }
    }
};

问题是在validationMessage更改时将此自定义绑定触发。只要validationMessage保持不变,此设置就可以正常工作,但使用confirmPassword时,根据错误,我有两个不同的消息:

self.confirmPassword = ko.observable("").extend(
   {
       required:
           {
               params: true,
               message: "Confirm Password is required"
           },
       equal:
           {
               params: self.password,
               message: "The confirmation does not match the password"
           }
    });

使用表单上的空格,第一条消息只占用一行,第二条消息占用两行。问题是,由于在两个消息之间切换时不会触发自定义绑定,因此我的幻灯片div的高度不会补偿validationMessage的新大小。 (即:首先我没有输入任何确认密码所以较短的消息是validationMessage和slideElement自定义绑定触发并将div设置为适当的高度。然后我将确认密码更改为密码以外的其他内容,它不会不匹配所以第二条消息成为新的validationMessage并显示在div中......但是自定义绑定不会触发,div的高度也不会补偿。)

有人知道如何在validationMessage更改时触发事件吗?

1 个答案:

答案 0 :(得分:1)

我找到了一种方法可以使它变得可行,但它并不优雅。似乎v2.0的knockout.validation可以通过使observable.error可观察来使这种情况更容易,但与此同时,你可以通过为具有多个validationMessages的observable进行第二次自定义绑定来解决像我这样的问题,你需要在邮件更改时执行某些操作:

查看模型添加:

self.confirmPassword.ValMsg = null;
    self.confirmPassword.ValMsgUpdate = ko.observable(false);
    self.confirmPassword.subscribe(function (newValue) {
        if (self.confirmPassword.ValMsg != self.confirmPassword.error)
        {
            self.confirmPassword.ValMsg = self.confirmPassword.error;
            self.confirmPassword.ValMsgUpdate(true);
            self.confirmPassword.ValMsgUpdate(false);
        }
    });

Html更新:

<div class="slideInner" data-bind="slideElement: confirmPassword.isModified() & !confirmPassword.isValid(), slideElementUpdate: confirmPassword.ValMsgUpdate()">

自定义绑定添加:

ko.bindingHandlers.slideElementUpdate = {
        update: function (element, valueAccessor, allBindings) {
            // First get the latest data that we're bound to
            var value = valueAccessor();

            // Next, whether or not the supplied model property is observable, get its current value
            var valueUnwrapped = ko.unwrap(value);

            if (valueUnwrapped == true) {
                var $outer = $(element).closest('.slideOuter');
                var $inner = $(element).closest('.slideInner');
                $outer.css('height', $inner.outerHeight(true) + "px");
            }
        }
    };