0

HTML列「ステップ番号」にノックアウト検証を配置して、値が一意であり、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/

問題は、検証を手動で再度実行した場合にのみ、1 回またはそれ以上にしか機能しないことです。2 つの理由があります。

1 つ目は、オブザーバブルが変更された場合にのみ検証が再度トリガーされることです。その場合、それは observableArray 'dataValues' です。また、observableArrays は、基になる配列を変更する場合、つまり要素を追加または削除する場合にのみ変更されます。ただし、要素が変更されても変更イベントは発生しません。

2 つ目の問題は、dataValues のデータがプレーンな JavaScript オブジェクトで構成されていることです。それらは ko.observables ではありません。したがって、双方向バインディングはありません (入力を更新しても、オブジェクトの値は更新されません)。

2 番目の問題は、データに 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 に答える