【问题标题】:knockout validation not working on required items淘汰赛验证不适用于所需项目
【发布时间】:2017-05-08 09:41:27
【问题描述】:

我对 Knockout 非常陌生,甚至对使用 Knockout 验证也很陌生。我有一些简单的必需输入,应该阻止提交表单。它仍然提交空输入。我不确定我做错了什么。

我创建了一个小提琴here。要进行测试,请在光标位于最后一个零售输入时按 Tab。这将添加一个新的空行。然后点击提交并查看控制台。 这是我的javascript代码:

var viewModel;

ko.validation.rules.pattern.message = 'Invalid.';
ko.validation.init({
  registerExtenders: true,
  messagesOnModified: true,
  insertMessages: true,
  parseInputAttributes: true,
  messageTemplate: null
}, true);

var itemModel = function () {
  var self = this;
  self.itemNo = ko.observable().extend( {required: true} );
  self.brocCode = ko.observable().extend( {required: true} );
  self.itemDesc = ko.observable().extend( {required: true} );
  self.retail = ko.observable().extend( {required: true} );
}

var itemsModel = function(items) {
    var self = this;
  //self.items = ko.observableArray(items);

  self.items = ko.mapping.fromJSON(items);

  self.checkItemNo = function(data) {
    console.log("blurred!");
    var itemNo = "abc";
    if (itemNo != "") {
      var item = "";
        /*
        $.each(fullItemList, function(i, v) {
        if (v.No.search(itemNo) != -1) {
        item = v.Description;
        return;
        }
        });
        if(item != "") {
        console.log("found: " + item);
        var match = ko.utils.arrayFirst(self.items, function(item) {
        return itemNo === item.itemNo;
        });
        */
      var match = false;
      item = "Mudguard front";
      if (!match) {
        console.log("not a match!");
        console.log(data);
        data.itemDesc(item);
      }
    }
  }

  self.addLine = function() {
    self.items.push( new itemModel() )
  };

  self.removeItem = function(item) {
    self.items.remove(item);
  };

  self.errors = ko.validation.group(self.items);
};

ko.bindingHandlers.enterPress = {
  init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
    var allBindings = allBindingsAccessor();
    element.addEventListener('keydown', function (event) {
      var keyCode = (event.which ? event.which : event.keyCode);
      if (keyCode === 13 || (!event.shiftKey && keyCode === 9)) {
        event.preventDefault();
        console.log("hit enter/tab!");
        bindingContext.$root.addLine();
        return false;
      }
      return true;
    });
  }
};

function GetItems() {
            //var itemsJSON = @Html.Raw(Json.Encode(Model.brochureItems));
            var itemsJSON =  '[{"brochureId":1,"itemNo":"1000","brocCode":"1000","itemDesc":"Bicycle","retail":13.5},{"brochureId":1,"itemNo":"1100","brocCode":"1100","itemDesc":"Front Wheel","retail":35},{"brochureId":1,"itemNo":"1120","brocCode":"1120","itemDesc":"Spokes","retail":12.5},{"brochureId":1,"itemNo":"1150","brocCode":"1150","itemDesc":"Front Hub","retail":5},{"brochureId":1,"itemNo":"1151","brocCode":"1151","itemDesc":"Axle Front Wheel","retail":14},{"brochureId":1,"itemNo":"120","brocCode":"120","itemDesc":"Loudspeaker, Black, 120W","retail":12.5},{"brochureId":1,"itemNo":"125","brocCode":"125","itemDesc":"Socket Back","retail":10}]';
            viewModel = new itemsModel(itemsJSON);
            ko.applyBindings(viewModel);
        }

$(document).ready(function () {
    GetItems();

  $('#brochureForm :submit').on('click', function(e) {
    e.preventDefault();  //prevent form from submitting

    if (viewModel.errors().length === 0)
      //if(viewModel.validationModel.isValid())
    {
      console.log("submitting!");
      //$("#brochureForm").submit();
    }
    else
    {
      console.log("not valid!");
    }
  });
});

【问题讨论】:

    标签: knockout.js knockout-validation


    【解决方案1】:

    我已经更新了你的小提琴https://jsfiddle.net/q7ahfzut/2/。您的问题仅仅是由于分组时的配置。您需要添加 { deep: true } 这将导致对所有已验证的 observable 运行验证。您可以添加live: true,这将导致在将新项目添加到数组时运行验证。其他需要注意的事项:

    1. 不需要任何 jquery - 您可以对点击事件和提交使用敲除
    2. 我从一开始就使用映射库为所有项目添加验证。

    希望对您的问题有所帮助!

    更新

    查看 ko 验证文档 here 以获取有关配置的更多信息

    更新 2

    要在评论中回答您的问题:查看mapping 插件以了解其工作原理(它的文档比验证要好一些。您可以create 按顺序拦截映射来操作生成的 ViewModel。options.data 包含您在映射到可观察对象之前映射的数据。了解它的最佳方法是阅读文档,然后慢慢地逐步了解它。

    【讨论】:

    • 哇!谢谢!我认为这是我弄错或丢失的一些设置。他们的文档缺乏,我希望他们的网站上有更多示例。
    • 我能请你给我解释一下这个sn-p吗? var mapping = { create: function(options) { return new itemModel(options.data);
    • 不客气。看看上面答案中的update 2
    猜你喜欢
    • 2012-02-18
    • 2015-02-28
    • 2018-03-25
    • 2016-05-14
    • 2012-11-04
    • 2011-08-09
    • 2016-02-17
    • 2014-01-06
    相关资源
    最近更新 更多