如何将ko.validation错误与相关的ViewModel字段名称联系在一起 [英] How to tie together ko.validation errors with related viewmodel field names

查看:51
本文介绍了如何将ko.validation错误与相关的ViewModel字段名称联系在一起的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Knockout.Validation,并且希望能够显示错误摘要,其中每行显示错误消息(很明显!)以及与之相关的视图模型上的字段名称,例如

  • 年龄-请输入一个数字
  • 出生日期-请输入正确的日期

到目前为止,我已经包装了一个封装了视图模型的validatedObservable,这会自动在我的视图模型上放置一个error数组,其中包含我所有的错误.但是,我看不到任何简单的方法来检索每个错误所涉及的字段.

我知道我可以自己遍历视图模型,并从isValid属性建立我自己的错误集合-这是我唯一的选择吗?

一旦有了字段名称,我就可以将验证摘要映射到该字段的相关友好"标签(例如,出生日期"而不是"DateOfBirth").

这是到目前为止我拥有的代码的简化版本:

ViewModel

function PersonModel(){
   var self = this;
   self.Age = ko.observable().extend({ number: true});

   self.DateOfBirth = ko.observable({ date: true});             
   self.Validate = function() {                           
       if (!self.isValid()) {                                         
          self.errors.showAllMessages();        
          return false;          
       }
       return true;
    };    

ko.validation.init({
                grouping: { deep: true, observable: true },
                registerExtenders: true,
                messagesOnModified: true,
                insertMessages: true
            });

ko.applyBindings(ko.validatedObservable(new PersonModel()));

HTML

<ul data-bind='foreach: model().errors' class="message">
    <li>
           <span data-bind='text:  $data'></span>
    </li>
</ul>

非常感谢

解决方案

您可以执行以下操作:

  • 添加一个friendlyName扩展器,为您的观测对象提供一个友好的名称
  • 缺少显示消息的绑定处理程序

好记的名字:

有史以来最简单的敲除扩展器:

ko.extenders.friendlyName = function (obs, options) {
    obs.friendlyName = options;
}

用法:self.Age = ko.observable(3).extend({ friendlyName: "My Age" });

显示邮件黑客:

敲除验证插件创建绑定处理程序validationMessage以显示错误消息.您可以直接使用它(带有一些html标记),也可以让插件使用配置选项insertMessages处理消息.

在这里,我只是编辑它创建的html(仍然调用原始绑定处理程序)以将friendlyName考虑在内:

var originalValidationMessageUpdate= ko.bindingHandlers.validationMessage.update;
ko.bindingHandlers.validationMessage.update = 
    function (element, valueAccessor, allBindingAccessor, viewModel, 
              bindingContext) {
        if (originalValidationMessageUpdate)
            originalValidationMessageUpdate(element, valueAccessor, 
                                            allBindingAccessor, viewModel,
                                            bindingContext);
        var prepend = (ko.isObservable(valueAccessor()) 
                            && valueAccessor().friendlyName)
                                  ? valueAccessor().friendlyName + " - "
                                  : "";

        $(element).html(prepend + $(element).html());
        // ^^^^ This is the line that is actually useful
    }

注意:我没有将friendlyName创建为可观察的,因为我猜它不会被更新,但是有可能做到这一点.

演示

I'm using Knockout.Validation and I'd like to be able to display an error summary where each line displays the error message (obviously!) and also the field name on the view model related to it, e.g.

  • Age - please enter a number
  • Date of birth - please enter a proper date

So far I've got a validatedObservable wrapping my view model, and this puts an errors array on my viewmodel automatically, containing all my errors. However I can't see any easy way to retrieve which field each error relates to.

I know I could traverse the view model myself, building up an errors collection of my own from the isValid property - is this my only option though?

Once I have the field name, I can map my validation summary to the related "friendly" label for that field (e.g. "Date of birth" rather than "DateOfBirth").

Here's a simplified version of the code I have so far:

ViewModel

function PersonModel(){
   var self = this;
   self.Age = ko.observable().extend({ number: true});

   self.DateOfBirth = ko.observable({ date: true});             
   self.Validate = function() {                           
       if (!self.isValid()) {                                         
          self.errors.showAllMessages();        
          return false;          
       }
       return true;
    };    

ko.validation.init({
                grouping: { deep: true, observable: true },
                registerExtenders: true,
                messagesOnModified: true,
                insertMessages: true
            });

ko.applyBindings(ko.validatedObservable(new PersonModel()));

Html

<ul data-bind='foreach: model().errors' class="message">
    <li>
           <span data-bind='text:  $data'></span>
    </li>
</ul>

Many Thanks

解决方案

You can do the following:

  • Add a friendlyName extender to provide a friendly name to your observables
  • Hack the binding handler that shows the messages

Friendly Name:

Simplest knockout extender ever:

ko.extenders.friendlyName = function (obs, options) {
    obs.friendlyName = options;
}

Usage: self.Age = ko.observable(3).extend({ friendlyName: "My Age" });

Display message hack:

Knockout validation plugin creates a bindinghandler validationMessage to display error messages. You can use it directly (with some html markup) or let the plugin handle the messages with the configuration option insertMessages.

Here I just edit the html it creates (the original binding handler is still called) to take the friendlyName into account:

var originalValidationMessageUpdate= ko.bindingHandlers.validationMessage.update;
ko.bindingHandlers.validationMessage.update = 
    function (element, valueAccessor, allBindingAccessor, viewModel, 
              bindingContext) {
        if (originalValidationMessageUpdate)
            originalValidationMessageUpdate(element, valueAccessor, 
                                            allBindingAccessor, viewModel,
                                            bindingContext);
        var prepend = (ko.isObservable(valueAccessor()) 
                            && valueAccessor().friendlyName)
                                  ? valueAccessor().friendlyName + " - "
                                  : "";

        $(element).html(prepend + $(element).html());
        // ^^^^ This is the line that is actually useful
    }

Note: I did not create friendlyName as an observable since I guess it will not be updated, but it is possible to do it.

Demo

这篇关于如何将ko.validation错误与相关的ViewModel字段名称联系在一起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆