0

我想对我的 html 列“Step No”进行剔除验证,以确保值应该是唯一的,并且从 1 到总步数之间没有间隙。

示例 html:

    <table>
      <tbody data-bind="foreach:dataValues">
        <tr>
          <td>
            <input type="text" data-bind="value: StepNo" />
          </td>
          <td>
            <input type="text" data-bind="value: Details" />    
          </td>
         <td>
            <input type="text" data-bind="value: Address" />    
          </td>
        </tr>
      </tbody>
    </table>

JavaScript:

function UniqueViewModel(){
    var dataValues=ko.observableArray([{StepNo:1,Details:"test1",Address:"address1"},
                                       {StepNo:2,Details:"test2",Address:"address2"},
                                       {StepNo:3,Details:"test3",Address:"address3"},
                                       {StepNo:4,Details:"test4",Address:"address4"}])

    }
ko.applyBindings(new UniqueViewModel());
4

1 回答 1

0

使用淘汰赛验证,您可以为您的 observableArray 创建一个规则:

var data =  [
    { StepNo: 1, Details: "test1", Address: "address1" }, 
    { StepNo: 1, Details: "test2", Address: "address2" }, 
    { StepNo: 3, Details: "test3", Address: "address3" }, 
    { StepNo: 4, Details: "test4", Address: "address4" }, 
];

function UniqueViewModel(initialData) {
     var self = this;
     self.dataValues = ko.observableArray(initialData).extend({
         validation: {
             validator: function (val, someOtherVal) {
                 var sorted = val.sort(function (a, b) {
                       return a.StepNo - b.StepNo; 
                 }), max = val.length;

                 for(var i = 0; i < max; i++) {
                     if(sorted[i].StepNo !== i+1) {
                         return false;
                     }
                 }
                 return true;
             },
             message: 'Your error message.',
             params: true
         }
     });
 }

var viewModel = new UniqueViewModel(data);
// show error
viewModel.dataValues.isModified(true);

 ko.applyBindings(viewModel);

然后你可以在某处显示消息:

<p data-bind="validationMessage: dataValues"></p>

小提琴:http: //jsfiddle.net/delixfe/AUYhy/

问题是,只有当您再次手动运行验证时,它才能工作一次或更好。有两个原因:

第一个是验证只会在可观察的变化时再次触发。在这种情况下,这就是 observableArray 'dataValues'。并且 observableArrays 仅在更改底层数组(即添加或删除元素)时才会更改。但它不会在元素更改时触发任何更改事件。

第二个问题是 dataValues 中的数据由纯 JavaScript 对象组成。它们不是 ko.observables。因此没有双向绑定(更新输入不会更新对象的值)。

您可以通过对数据使用 ko.observable 来解决第二个问题:

var data = [
    { StepNo: ko.observable(1), Details: "test1", Address: "address1" }, 
    { StepNo: ko.observable(1), Details: "test2", Address: "address2" }, 
    { StepNo: ko.observable(3), Details: "test3", Address: "address3" }, 
    { StepNo: ko.observable(4), Details: "test4", Address: "address4" }
];

要解决第一个问题,您必须确保对 observableArray 和 StepNo 的更改做出反应。因此,您可以使用 ko.computed。

function UniqueViewModel(initialData) {
    var self = this;

    self.dataValues = ko.observableArray(initialData);

    self.dataValuesStepsValid = ko.computed(function () {
        // the call to self.dataValues() subscribes to the observableArray
        // and the call to element.StepNo() inside the mapping to each element
        var numbers = ko.utils.arrayMap(self.dataValues(), function (element) {
            return element.StepNo();
        });
        var max = numbers.length;
        numbers.sort(function (a, b) {
            return a - b;
        });

        for (var i = 0; i < max; i++) {
            // when changing the data in the table we get strings
            if (numbers[i] != i + 1) {
                return false;
            }
        }
        return true;
    });
}


var viewModel = new UniqueViewModel(data);

ko.applyBindings(viewModel);

您可以这样显示消息:

<p data-bind="ifnot: dataValuesStepsValid">Your error message</p>

以下小提琴表明:http: //jsfiddle.net/delixfe/UzDZd/

或者,您可以将验证规则附加到计算的。

于 2013-01-27T14:10:31.813 回答