简体   繁体   English

Knockout验证没有使用knockout自定义绑定触发

[英]Knockout validation not firing with knockout custom binding

I have a knockout custom binding handler for an input that I need to have validated by knockout-validation. 我有一个敲除自定义绑定处理程序,我需要通过knockout-validation验证输入。 However nothing I've done has worked. 然而,我所做的一切都没有奏效。 Validation is not fired. 验证不会被触发。 I can get validation firing on a plain ko value binding on an input bound to the same viewmodel property. 可以在绑定到同一viewmodel属性的输入上的纯ko值绑定上获取验证。

What I've found from my research (ko docs, ko-validation github docs and this SO question validationOptions not working with custom bindingHandlers amongst many others) is that you need: 我从我的研究中发现了(ko docs,ko-validation github docs和这个SO问题validationOptions不能与自定义bindingHandlers一起使用 ),你需要:

ko.validation.makeBindingHandlerValidatable("yourcustombindinghandlername");

to make KO-validation take notice of your custom binding handler. 使KO验证注意到您的自定义绑定处理程序。 I have that and I'm still getting no joy. 我有,我仍然没有快乐。

I've tried debugging through knockout-validation.js for both the value binding and custom binding to see what's happening differently but I can't work out what the entry point for the custom binding validation would be. 我已经尝试通过knockout-validation.js调试值绑定和自定义绑定,看看发生了什么不同但我无法弄清楚自定义绑定验证的入口点是什么。 My js isn't that strong TBH. 我的js不是那么强大的TBH。

Here's a very simplified version of the code: 这是代码的一个非常简化的版本:

HTML: HTML:

<div>
<div id="vehicleQuoteDetails">
    <div>            
        <div>
            <!--with custom binding-->
            <input data-bind="vehiclemileage: quote.mileage, fieldName: 'mileage'" type="text" id="quoteMileage">
            <!--without custom binding-->
            <input data-bind="value:quote.mileage" class="form-control"/>
        </div>
    </div>
</div>
</div>

Here's the JS: 这是JS:

Custom Binding Handler: 自定义绑定处理程序:

ko.bindingHandlers.vehiclemileage = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        $(element).on("blur", function (evt) {
            if (evt.timeStamp !== undefined) {
                var fieldName = allBindingsAccessor().fieldName;
                bindingContext.$root.update[fieldName]($(element).val());

            }
            //return true;
        });
        //return true;
    },
    update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var value = ko.utils.unwrapObservable(valueAccessor());
        $(element).val(value);
        //return true;
    }
}

Viewmodel: 视图模型:

function JobQuoteViewModel() {
    var self = this;

    self.quote = {};

    self.getQuote = function () {

        self.quoteMapping = {
            "mileage": {
                create: function (options) {
                    return ko.observable(options.data).extend({ required: true });
                }
            }
        }

                var quoteResult = { mileage:1234 }

        ko.validation.init();
        ko.validation.makeBindingHandlerValidatable("vehiclemileage");
        self.quote = ko.mapping.fromJS(quoteResult, self.quoteMapping);
        ko.applyBindings(self);

        //$.ajax({
        //    url: "webapplication6/Home/GetQuote",
        //    type: "GET",
        //    dataType: "JSON",
        //    success: function (result) {
        //        ko.validation.init();
        //        ko.validation.makeBindingHandlerValidatable("vehiclemileage");
        //        self.quote = ko.mapping.fromJS(result.data, self.quoteMapping);
        //        ko.applyBindings(self);
        //    }
        //});
    };

    self.update = {
        mileage: function (value) {

            alert('mileage: ' + value);
        }
    }
    self.getQuote();
}

View model instantiation: 查看模型实例化:

var jobQuoteVM = new JobQuoteViewModel();

And here's the fiddle for the above : https://jsfiddle.net/stevedavey/1j6vphya/ 这里是上面的小提琴: https//jsfiddle.net/stevedavey/1j6vphya/

In the example I've got two inputs: one bound to a custom binding handler and one to a simple value binding. 在示例中,我有两个输入:一个绑定到自定义绑定处理程序,一个绑定到简单的值绑定。 The latter is to demonstrate the validation on the plain value binding works fine. 后者是为了证明对普通值绑定的验证工作正常。

The input on the left is the one bound to a custom binding handler and the input on the right is the value binding. 左侧的输入是绑定到自定义绑定处理程序的输入,右侧的输入是值绑定。

TIA for any help. TIA提供任何帮助。

Looks like you don't properly update the observable. 看起来你没有正确更新observable。 You could for example use a simple computed to do so: 例如,您可以使用一个简单的计算器来执行此操作:

https://jsfiddle.net/otjg2L8z/2/ https://jsfiddle.net/otjg2L8z/2/

I've slightly amended your custom binding: 我稍微修改了你的自定义绑定:

ko.bindingHandlers.vehiclemileage = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {

        var formattedValue = ko.pureComputed({
            read: function () {
                var text = valueAccessor()();
                return text;
            },
            write: function (newValue) {
                valueAccessor()(newValue);
            }
        });
        ko.utils.registerEventHandler(element, "blur", function (evt) {
            var modelValue = valueAccessor(),
                elementValue = $(element).val();
            if (ko.isWriteableObservable(modelValue)) {
                formattedValue(elementValue);
            }    

            if (evt.timeStamp !== undefined) {
                var fieldName = allBindingsAccessor().fieldName;
                bindingContext.$root.update[fieldName]($(element).val());

            }
        });

        //return true;
    },
    update: function (element, valueAccessor, allBindingsAccessor,     viewModel, bindingContext) {
        var value = ko.utils.unwrapObservable(valueAccessor());
        $(element).val(value);
        //return true;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM