нокаут проверка подписка обновление после изменения

У меня есть модель «Параметры поиска», которая имеет два свойства title и priceMax, оба обязательны. Когда пользователь изменяет свойства, скрипт обновляет количество предложений от API. Обновление выполняется, когда в модели searchParameters нет ошибок. Проблема в методе, который возвращает количество ошибок в модели. Когда title и priceMax имеют значение, метод возвращает ошибки, только когда я снова изменяю свойство модели, метод возвращает значение 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


person Łukasz Walkowiak    schedule 20.07.2016    source источник


Ответы (1)


Это связано с порядком, в котором вы применяете экстендеры. Когда вы расширяете наблюдаемую, каждый расширитель запускается последовательно на результат предыдущего.

Таким образом, ваш код расширяет исходный наблюдаемый объект (где он подписывается на изменения), а затем наблюдаемый снова расширяется, чтобы сделать его обязательным.

Честно говоря, я не уверен на 100%, что knockout-validation делает с исходным наблюдаемым, что вызывает поведение, которое вы видите, но если вы измените порядок своих расширителей (как в этот jsFiddle), то вы гарантируете, что ваш пользовательский расширитель будет работать с «конечным» наблюдаемым и, следовательно, будет работать так, как вы ожидаете.

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