敲除验证订阅更改后更新

knockout validation subscribe update after change

我有模型 'search Parameters',它有两个属性 title 和 priceMax,两者都是必需的。当用户更改属性时,脚本会从 API 更新报价数量。当模型 'searchParameters' 没有错误时,执行更新。问题出在方法中,return 计算模型中的错误。当 title 和 priceMax 有值时,方法 return 错误,只有当我再次更改模型的 属性 方法 return 值 0 时。知道吗?这是我的解决方案。

HTML

   <fieldset>
      <div class="row">
        <label>Title:</label>
        <input type="text" data-bind="textInput: searchParameters.title" />

      </div>

      <div class="row">
        <label>Price max:</label>
        <input data-bind="textInput: searchParameters.priceMax" />

      </div>
      <div class="row">
        <label>count offers:</label>
        <span data-bind="text: countOffers"></span>
      </div>
      <div class="row" data-bind="visible:visibleProgress">
        progress...
      </div>
    </fieldset>

JS

function ViewModel() {
  var self = this;
  self.countOffers = ko.observable(0);
  self.visibleProgress = ko.observable(false);
  ko.extenders.refreshCountOffers = function(target, timeout) {
    var timerId = null;
    target.subscribe(function(newValue) {
      console.log(self.errors());
      if (self.errors().length === 0) {
        clearTimeout(timerId);
        timerId = setTimeout(function() {
          self.visibleProgress(true);
          //mock api
          $.ajax({
            url: '/echo/js/?js=' + Math.floor((Math.random() * 100)),
            data: {
              delay: 2
            },
            complete: function(response) {
              self.countOffers(response.responseText);
              self.visibleProgress(false);
            }
          });
          //mock api
        }, 500);
      } else
        self.countOffers(0);
    });
    return target;
  };
  self.searchParameters = {
    title: ko.observable().extend({
      refreshCountOffers: 500
    }).extend({
      required: true
    }),
    priceMax: ko.observable().extend({
      refreshCountOffers: 500
    }).extend({
      required: true
    })
  };
  self.errors = ko.validation.group(self.searchParameters);
};

var model = new ViewModel();
ko.applyBindings(model);

我的jsfiddle

这是因为您应用增效剂的顺序。当你扩展一个 observable 时,每个扩展器都是 运行 在前一个扩展器的结果上串行。

因此,您的代码扩展了 原始 可观察对象(它订阅更改的地方),然后再次扩展可观察对象以使其成为必需的。

老实说,我不是 100% 确定 knockout-validation 对导致您看到的行为的源可观察对象做了什么,但是如果您颠倒扩展程序的顺序(如 this jsFiddle ) 然后你保证你的自定义扩展器将在 'final' observable 上运行,因此将按你期望的那样工作。

self.user = {
  firstName: ko.observable().extend({
    required: true,
    refreshCountOffers: 500
  }),
  lastName: ko.observable().extend({
    required: true,
    refreshCountOffers: 500
  })
};