1

我尝试实施以下建议,但每次更新值时似乎都没有触发所需的反应。这可能是由于我的实施,因为我是 Knockout 的新手。

我有一个绑定到 TextBoxFor 的 observable (Amount)。

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

当输入一个值时,需要对其进行验证以确保它不超过 999999。除此之外,如果该值小于 50,则需要将其设置为 50。每次“量的变化。

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

据我所知,淘汰赛验证不提供任何直接从规则定义访问 observable 的能力。如果可能的话,您可以在自定义验证规则中强制该值。

我发现的最佳选择是为您要强制的每个规则创建一个自定义扩展程序。

这是“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

非常相似的问题在这里: Make Knockout applyBindings to Treat select options as number

尽管订阅,您仍可以计算值。它看起来像:

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);

编辑

我还查看了您在此处使用的扩展器。您可以添加到您的扩展器最小值并将其传递给您的 observable 参数。您显然必须在扩展器的 write 方法中编写一些代码

就像是:

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


   }
...
}
于 2013-04-21T20:15:34.463 回答