1

以下の提案を実装しようとしましたが、値が更新されるたびに必要な反応を引き起こすようには見えませんでした。これは、Knockout を初めて使用するための実装が原因である可能性があります。

私は、TextBoxFor にバインドされているオブザーバブル (Amount) を持っています。

@Html.TextBoxFor(m => m.Amount, new { type = "number", data_bind = "value: Amount" })

「金額」が変わります。

var viewModel = {
    Amount: ko.observable().extend({numeric: 0, max: 999999})
};

解決策を実装しようとしましたが (以前の投稿への回答で)、これらを機能させることができませんでした。

私が思いついた最善の方法は、次のように計算されたものを作成することです。これにより、入力値がチェックされ、最初の試行で正しく更新されます。その後の値の変更は画面上の変更をトリガーしませんが、コードをステップ実行すると、ViewModel.Amount 値が更新されるように見えます。

@Html.TextBoxFor(m => m.Amount, new { type = "number", data_bind = "value: amountMin" })


quoteVehicleViewModel.VehicleMileage = ko.observable(0);


viewModel.amountMin = ko.computed({
    read: function () {
        return viewModel.Amount();  
    },
    write: function (value) {
        if (value < 50) {
            viewModel.Amount(50);
        }
    }
}).extend({ numeric: 0, max: 999999 });

** コンソールに入力された "viewModel.Amount()" では、値が 1000 として表示されますが、画面上の値は入力された値として表示されます。

感謝して受け取った支援

ジョン

4

2 に答える 2

1

私が知る限り、ノックアウト検証では、ルール定義からオブザーバブルに直接アクセスする機能は提供されません。それが可能であれば、カスタム検証ルールで値を強制することができます。

私が見つけた最良の代替手段は、強制したいルールごとにカスタム エクステンダーを作成することです。

「min」ルールの強制エクステンダーの例を次に示します。

  ko.extenders.coerceMin = function (target, enable) {
      //collect rule values
      var minRule = ko.utils.arrayFirst(target.rules(), function (val) {
          return val.rule === "min"
      });
      if (minRule === null) {
          throw Error("coerceMin extender must be used in conjunction with the 'min' knockout validation rule");
      }
      var minValue = minRule.params;
      //listen for changes and coerce when necessary
      var subscription = null;
      if (enable && !subscription) {
          subscription = target.subscribe(function (newValue) {
              if (!isNaN(newValue)) {
                  var newValueAsNum = parseFloat(+newValue);
                  var valueToWrite = newValueAsNum < minValue ? minValue : newValueAsNum;
                  //only write if it changed
                  if (valueToWrite !== newValue) {
                      target(valueToWrite);
                  }
              }
          });
      } else {
          if (subscription) {
              subscription.dispose();
          }
      }

      //return the original observable
      return target;
  };

次のようにビューモデルに適用できます。

var viewModel = {
    Amount: ko.observable()
              .extend({numeric: 0, min: 50, max: 999999})
              .extend({coerceMin: true});
};

ここに実証するフィドルがあります: http://jsfiddle.net/f2rTR/1/

于 2013-04-22T14:46:12.890 に答える
0

非常によく似た問題は次のとおりです。 Knockout applyBindings を作成して、選択したオプションを数値として扱うようにします。

購読しているにもかかわらず、計算された値を作成できます。次のようになります。

var viewModel = {
    _amount: ko.observable(100).extend({numeric: 0, max: 999999, reset: true}),
    Amount : ko.computed(function(){
       return _amount < 50 ? 50 : _amount;
   })
};


ko.applyBindings(viewModel);

編集

ここで使用したエクステンダーも調べました。エクステンダーの最小値に追加して、オブザーバブルの引数を渡すことができます。エクステンダーの書き込みメソッドで明らかにいくつかのコードを記述する必要があります

何かのようなもの:

ko.extenders.numeric = function(target, min) {
...
   write:function(v){
      ...
      if(v<50) v=50;
      ...
      target(v)


   }
...
}
于 2013-04-21T20:15:34.463 に答える