使用敲除验证来确保数组中的值是唯一的

时间:2016-05-09 13:06:51

标签: knockout.js knockout-validation

我的HTML代码:

<button  data-bind="click: addmyEvent">
Add New Event</button><p />
<div class="row" data-bind="foreach: myevents">
 <input type="text" data-bind="value: name" />
<button  data-bind="click: $root.addProperty">Add Property</button><p />
<div data-bind="foreach: properties">
<input type="text" data-bind="value: name" />
<button data-bind='click: addOptionValue'>Add Option </button>
        <div data-bind="foreach: optionvalues">
          <div class="form-inline">
            <input type="text" data-bind="value: optionvalue" />
          </div>
        </div>
</div>
</div>
<pre data-bind="text: JSON.stringify(ko.toJS($root), null, 2)"></pre>

我的javascript代码:

function myEvent(data){
    var self = this
    self.name=ko.observable(data.name);
    self.properties = ko.observableArray(data.propertydetails);
}

 function Property(data) {
     var self = this
     self.name=ko.observable(data.name);
     self.optionvalues = ko.observableArray(data.optionvalue);
     self.addOptionValue = function (properties) {
         properties.optionvalues.push({ optionvalue: "" });
     }
 }
 var myViewModel = function () {
      var self = this
            self.myevents = ko.observableArray([]);  

    self.addmyEvent = function () {
        self.myevents.push(new myEvent({name:"", properties: ko.observableArray() }));
    }
    self.addProperty = function (ev) {
        ev.properties.push(new Property({name:"", optionvalues: ko.observableArray()}));
    };
}
ko.applyBindings(new myViewModel());

Jsfiddle:https://jsfiddle.net/o6juohxL/9/ 1

我想使用敲除验证并确保..

  • a)name数组中的viewmodel.myevents字段是唯一的
  • b)name数组中的viewmodel.myevents[].properties字段是唯一的
  • c)optionvalue数组中的viewmodel.myevents[].properties[].optionvalues字段是唯一的

我在用户提供的规则here中找到了isUnique规则,但我无法弄清楚如何使用相同规则。

1 个答案:

答案 0 :(得分:1)

您找到的isUnique贡献应该适用于您的用例。我将尝试解释验证器的工作原理,以便您可以针对所有用例实现它。

ko.validation的基础知识:

  1. 首先,您必须确保使用自定义规则加载和扩展ko.validation脚本。
  2. 使用.extend( /* options */ )
  3. 扩展需要验证的可观察对象

    现在,我们可以查看isUnique实现。在文档中,您可以看到需要提供具有ko.observableArray属性的数组/ Objectarray。让我们保持简单并与第一个一起使用。

    function myEvent(data) {
      var self = this;
      var eventNames = ko.observableArray([]);
    
      self.name = ko.observable(data.name).extend({
        required: true,
        isUnique: eventNames
      });
    };
    

    如果您在自定义规则中放置断点,则可以检查规则是否正确运行。但它会使用一个空数组来检查唯一身份。让我们解决这个问题。

    myEvent个实例对其他事件一无所知&#39;名。这组事件存在于myViewModel。此外,它是一个可观察的对象数组而不是事件名。我们将创建一个新的computed变量来创建一个事件名称数组,并且我们会将引用传递给我们的myEvent构造函数:

    // Create a computed array of names
    var myEventNames = ko.computed(function() {
      return self.myevents().map(function(event) { return event.name(); });
    });
    
    // When creating a new event, give it access to this array
    self.addmyEvent = function() {
      self.myevents.push(new myEvent({
        name: "",
        properties: ko.observableArray()
      }, myEventNames));
    };
    

    现在,我们可以返回myEvent并从构造函数中删除eventNames声明。它现在是myViewModel传递的参数。

    function myEvent(data, eventNames) {
      var self = this;
      self.name = ko.observable(data.name).extend({
        required: true,
        isUnique: eventNames
      });
    
      // Other code ...
    };
    

    这是否可以让您自己找出其他实现?让我知道你的想法。

    这里是我给出的例子的小提琴:https://jsfiddle.net/ute3uem6/

    修改:如果您不想使用计算机丢弃视图模型,可以使用predicate规则中的isUnique功能:

    这就是它的工作原理:如果你提供一个方法告诉isUnique 如何将当前值与数组中的值进行比较,则不需要映射{{ 1}}可观察到一个字符串数组。它做了同样的事情,但使用了不同的方法。我想这是你选择的个人偏好。

    myevents