Сравнение двух полей с проверкой нокаута

У меня есть модель представления для формы, в которую я пытаюсь добавить проверку с помощью проверки нокаута.

fromDate: ko.observable(
            moment().subtract('days', 1).startOf('day').format(dateFormat)
          ),
toDate: ko.observable(
            moment().startOf('day').format(dateFormat)
        ),

Мне нужно убедиться, что дата начала меньше, чем дата. Кажется, я не могу получить какую-либо форму пользовательского валидатора, чтобы подобрать ссылку на второй наблюдаемый. Мне нужно что-то вроде:

toDate: ko.observable(moment().startOf('day').format(dateFormat)).extend({
          validation: {
            validator: function (val, someOtherVal) {
                return moment(val) >= moment(someOtherVal);
            },
            message: 'Must be greater or equal to From Date',
            params: viewModel.fromDate()
          }
        }),

Есть идеи?

Обновить

Я уверен, что уже пробовал это, но перемещение метода расширения в функцию загрузки работает.

$(function () {
    ko.validation.configure({ decorateElement: true });

    viewModel.toDate.extend({
    validation: {
            validator: function (val, someOtherVal) {
                return moment(val) >= moment(viewModel.fromDate());
            },
            message: 'To date must be greater than from date',
        }
    });

    ko.applyBindings(viewModel);
});

person Matt    schedule 29.01.2013    source источник


Ответы (4)


основные правила Knockout-validation не могут обрабатывать наблюдаемые в качестве параметров для проверки. Но уже есть push-запрос, который должен это исправить: https://github.com/ericmbarnard/Knockout-Validation/pull/217

Поэтому вы должны использовать для этого пользовательскую роль. Вы должны вставить параметр как функцию (опуская круглые скобки). Это позволит нокаут-валидации реагировать на изменения в параметре.

function ViewModel() {
    var self = this; // capture this to be able to reference properties

    self.fromDate = ko.observable(
        moment().subtract('days', 1).startOf('day').format(dateFormat)
    );
    self.toDate = ko.observable(
        moment().startOf('day').format(dateFormat)
    ).extend({
      validation: {
        validator: function (val, someOtherVal) {
            return moment(val) >= moment(someOtherVal());
        },
        message: 'Must be greater or equal to From Date',
        params: self.fromDate
      }
    }),
}
person delixfe    schedule 30.01.2013

Глядя на документацию, вы можете сделать это так:

ko.validation.rules['greaterThan'] = {
    validator: function (val, otherVal) {
        return val > otherVal;
    },
    message: 'The field must be greater than {0}'
};

ko.validation.registerExtenders();

fromDate: ko.observable(
            moment().subtract('days', 1).startOf('day').format(dateFormat)
          ),
toDate: ko.observable(
            moment().startOf('day').format(dateFormat)
        ).extend({ greaterThan: fromDate() });

Это не проверено, и я не знаю, хотите ли вы передать fromDate() или fromDate, а затем в валидаторе использовать otherVal().

person Paul Manzotti    schedule 29.01.2013
comment
Уже пробовал, все равно выдает "Uncaught TypeError: Cannot call method" fromDate" of undefined" - person Matt; 29.01.2013
comment
У вас есть ссылка внутри модели представления (var self = this) и попробуйте moreThan: self.fromDate() ? - person Paul Manzotti; 29.01.2013
comment
Да, кажется, что методы расширения не могут ссылаться на модель представления, если они объявлены внутри нее. Регистрация их, когда есть экземпляр модели представления, кажется, работает. обратите внимание, что я использовал синтаксис var vm ={}, а не синтаксис на основе функций, тогда это может быть не так. - person Matt; 29.01.2013
comment
Я предполагаю, что это потому, что в то время, когда вы добавляли метод расширения, модель представления еще не закончила инициализацию и, следовательно, не существовала, следовательно, она не определена в вашем методе проверки. - person Paul Manzotti; 29.01.2013
comment
Последняя строка в ответе Пола должна выглядеть так: ).extend({ greatThan: this.fromDate }); т. е. параметр должен передаваться без круглых скобок. а третья строка должна выглядеть так: return val › otherVal(); -- otherVal в скобках. Так это работает. - person Vadim Loboda; 30.01.2013

Это немного поздно для вечеринки, но когда я гуглю «соответствие поля пароля knockoutjs», это лучший результат.

Мне нужен сопоставитель без использования расширения проверки, потому что мне не нужны все предложения этого пакета.

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

  ko.extenders.match = function(target, match_original) {
  target.match_ok = ko.observable();
  function copy(value) {
    target.match_ok(value == match_original());
  }
  function original(value) {
    target.valueHasMutated();
  }
  copy(target());
  target.subscribe(copy);
  match_original.subscribe(original);
  return target;
};

Вот jsfiddle, чтобы лучше проиллюстрировать функциональность https://jsfiddle.net/8nugva9f/13/

ХТН

person Bob Smith    schedule 19.09.2017

this.fromDate= ko.observable(null).extend({
        date: true,

    });

this.toDate = ko.observable(null).extend({
        date: true,
        min: this.fromDate,

    });

Попробуй это.

person PriyankaLT    schedule 25.10.2017