Knockout验证:如何将无效条目保留在viewmodel之外

时间:2016-02-14 20:37:11

标签: knockout.js knockout-validation

我有一些页面,我的Knockout视图模型根据用户输入的数字字段执行汇总计算。我有适当的数字验证规则。

但是,如果用户输入非数字值,则模型必须接受该值才能使验证完成其工作。因此,非数字值会流入汇总计算,但会产生不良结果。

我想要的是数字验证规则阻止非数字数据进入我的viewmodel。有没有办法实现这种行为?

我意识到我可以使用ko扩展器或输入掩码来拒绝非数字输入,但我宁愿用户被告知他们的错误并自行修复,而不是简单地还原用户的条目在输入字段中。

1 个答案:

答案 0 :(得分:0)

我使用的典型解决方案是将待创建项及其值存储在根视图模型的单独部分中,并仅在(a)验证通过和(b)用户时将其推送到列表中指示系统这样做。例如:



function Item(name, nr){
  this.name = ko.observable(name || "");
  this.number = ko.observable(nr || 0);
}

function Root(initialItems) {
  var self = this;
  
  self.items = ko.observableArray(initialItems);
  
  self.total = ko.computed(function() { 
    return self.items().reduce(function(a, b) {
      return a + parseInt(b.number(), 10);
    }, 0);
  });
  
  self.newItem = ko.observable(new Item());
  
  self.addItem = function() {
    // Stubbing actual validation:
    if (!self.newItem().name()) { alert('name required!'); return; }
    if (self.newItem().number() <= 0) { alert('positive nr required!'); return; }
    
    // Actual work:
    self.items.push(self.newItem());
    self.newItem(new Item());
  }
}

ko.applyBindings(new Root([new Item("Apples", 3), new Item("Oranges", 5)]));
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

Total number: <strong data-bind="text: total"></strong>
<hr>
Items:
<ul data-bind="foreach: items">
  <li>
    <span data-bind="text: name"></span>
    <span data-bind="text: number"></span>
  </li>
</ul>
<hr>
<div data-bind="with: newItem">
  New Item:<br>
  <input placeholder="name" data-bind="textInput: name">
  <input placeholder="name" data-bind="textInput: number" type="number">
  <br><button data-bind="click: $root.addItem">Add</button>
</div>
&#13;
&#13;
&#13;