使用敲除验证确保数组中的值是唯一的
Using knockout validation to ensure values in an array are unique
我的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)
viewmodel.myevents
数组中的 name
字段是唯一的
- b)
name
数组中的 viewmodel.myevents[].properties
字段是唯一的
- c)
optionvalue
viewmodel.myevents[].properties[].optionvalues
数组中的字段是唯一的
我在用户贡献的规则中找到了 isUnique
规则 here 但我无法弄清楚如何使用它。
您找到的 isUnique
贡献应该适用于您的用例。我将尝试解释验证器的工作原理,以便您可以为所有用例实施它。
ko.validation
的基础知识:
- 首先,您必须确保
ko.validation
脚本已加载并使用自定义规则进行了扩展。
- 使用
.extend( /* options */ )
扩展需要验证的可观察对象
现在,我们可以看看 isUnique
实现。在文档中,您可以看到您需要提供数组/ko.observableArray
或 Object
以及 array
属性。让我们保持简单并使用第一个。
function myEvent(data) {
var self = this;
var eventNames = ko.observableArray([]);
self.name = ko.observable(data.name).extend({
required: true,
isUnique: eventNames
});
};
如果您在自定义规则中放置一个断点,您将能够检查规则是否正确运行。但它将使用一个空数组来检查唯一性。让我们解决这个问题。
A myEvent
实例对其他事件的名称一无所知。这组事件存在于 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 ...
};
这是否使您能够自己找出其他实现方式?让我知道你的想法。
这是一个 fiddle 我举的例子:https://jsfiddle.net/ute3uem6/
编辑:如果你不想用计算乱丢你的视图模型,你可以使用 isUnique
规则中的 predicate
功能:
它是这样工作的:如果你提供了一个方法来告诉isUnique
如何将当前值与数组中的值进行比较,你不需要将 myevents
observable 映射到字符串数组。它做同样的事情,但使用不同的方法。我想你选择哪种方式是个人喜好。
isUnique: {
array: events,
predicate: function(currentEvent, currentValue) {
return currentEvent.name() === currentValue;
}
}
我的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)
viewmodel.myevents
数组中的name
字段是唯一的 - b)
name
数组中的viewmodel.myevents[].properties
字段是唯一的 - c)
optionvalue
viewmodel.myevents[].properties[].optionvalues
数组中的字段是唯一的
我在用户贡献的规则中找到了 isUnique
规则 here 但我无法弄清楚如何使用它。
您找到的 isUnique
贡献应该适用于您的用例。我将尝试解释验证器的工作原理,以便您可以为所有用例实施它。
ko.validation
的基础知识:
- 首先,您必须确保
ko.validation
脚本已加载并使用自定义规则进行了扩展。 - 使用
.extend( /* options */ )
扩展需要验证的可观察对象
现在,我们可以看看 isUnique
实现。在文档中,您可以看到您需要提供数组/ko.observableArray
或 Object
以及 array
属性。让我们保持简单并使用第一个。
function myEvent(data) {
var self = this;
var eventNames = ko.observableArray([]);
self.name = ko.observable(data.name).extend({
required: true,
isUnique: eventNames
});
};
如果您在自定义规则中放置一个断点,您将能够检查规则是否正确运行。但它将使用一个空数组来检查唯一性。让我们解决这个问题。
A myEvent
实例对其他事件的名称一无所知。这组事件存在于 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 ...
};
这是否使您能够自己找出其他实现方式?让我知道你的想法。
这是一个 fiddle 我举的例子:https://jsfiddle.net/ute3uem6/
编辑:如果你不想用计算乱丢你的视图模型,你可以使用 isUnique
规则中的 predicate
功能:
它是这样工作的:如果你提供了一个方法来告诉isUnique
如何将当前值与数组中的值进行比较,你不需要将 myevents
observable 映射到字符串数组。它做同样的事情,但使用不同的方法。我想你选择哪种方式是个人喜好。
isUnique: {
array: events,
predicate: function(currentEvent, currentValue) {
return currentEvent.name() === currentValue;
}
}