Как использовать aurelia-validate со свойствами объекта для проверки?

Я использую aurelia-validate, и моя валидация работает нормально, если я использую переменные, но мне это нужно для проверки свойств объекта, а не переменной:

Вот что работает:

  import {Validation} from 'aurelia-validation';
  import {ensure} from 'aurelia-validation';
  import {ItemService} from './service';

  export class EditItem {
    static inject() {
      return [Validation, ItemService];
    }

    @ensure(function(it){
      it.isNotEmpty()
        .hasLengthBetween(3,10);
    })
      name = '';

    @ensure(function(it){
      it.isNotEmpty()
        .hasMinLength(10)
        .matches(/^https?:\/\/.{3,}$/) //looks like a url
        .matches(/^\S*$/); //no spaces
    })
      url = '';

    constructor(validation, service) {
      this.validation = validation.on(this);
      this.service = service;
    }

    activate(params){
      return this.service.getItem(params.id).then(res => {
        console.log(res);
        this.name = res.content.name; //populate
        this.url = res.content.url;
      });
    }

    update() {
      this.validation.validate().then(
        () => {
          var data = {
            name: this.name,
            url: this.url
          };

          this.service.updateItem(data).then(res => {
            this.message = "Thank you!";
          })
        }
      );
    }
  }

Вот что я пытаюсь сделать (но не работает)... также я не уверен, что лучше оставить свойства в классе или иметь свойство с именем this.item который содержит свойства (это типичный угловой способ):

  import {Validation} from 'aurelia-validation';
  import {ensure} from 'aurelia-validation';
  import {ItemService} from './service';

  export class EditItem {
    static inject() {
      return [Validation, ItemService];
    }

    @ensure(function(it){
      it.isNotEmpty()
        .hasLengthBetween(3,10);
    })
      this.item.name; //no assignment here should happen 

    @ensure(function(it){
      it.isNotEmpty()
        .hasMinLength(10)
        .matches(/^https?:\/\/.{3,}$/) //looks like a url
        .matches(/^\S*$/); //no spaces
    })
      this.item.url; //no assignment?

    constructor(validation, service) {
      this.validation = validation.on(this);
      this.service = service;
      this.item = null;
    }

    activate(params){
      return this.service.getItem(params.id).then(res => {
        console.log(res);
        this.item = res.content; //populate with object from api call
      });
    }

    update() {
      this.validation.validate().then(
        () => {
          var data = {
            name: this.item.name,
            url: this.item.url
          };

          this.service.updateItem(data).then(res => {
            this.message = "Thank you!";
          })
        }
      );
    }
  }

Может ли кто-нибудь дать мне несколько советов о том, как использовать валидатор для существующего объекта (для страницы редактирования)?

2 ответа

Решение

Проверка работает в любых ситуациях, но использование декоратора @ensure можно использовать только для объявления ваших правил в простых свойствах (как вы узнали).

Следовательно...

Вариант a: замените декоратор sure на свободный метод API "sure", который поддерживает "вложенные" или "сложные" пути привязки, такие как:

import {Validation} from 'aurelia-validation';
import {ItemService} from './service';

export class EditItem {
static inject() {
  return [Validation, ItemService];
}

constructor(validation, service) {
  this.validation = validation.on(this)
    .ensure('item.url')
      .isNotEmpty()
      .hasMinLength(10)
      .matches(/^https?:\/\/.{3,}$/) //looks like a url
      .matches(/^\S*$/)
    .ensure('item.name')
      .isNotEmpty()
      .hasLengthBetween(3,10);
  this.service = service;
  this.item = null;
}

activate(params){
  return this.service.getItem(params.id).then(res => {
    console.log(res);
    this.item = res.content; //populate with object from api call
  });
}

update() {
  this.validation.validate().then(
    () => {
      var data = {
        name: this.item.name,
        url: this.item.url
      };

      this.service.updateItem(data).then(res => {
        this.message = "Thank you!";
      })
    }
  );
}

}

Примечание. Вы можете настроить проверку еще до установки элемента. Круто, нет?

Вариант b: поскольку правила проверки являются специфическими для элемента, вы можете переместить свои правила проверки в свой класс элементов, используя вместо этого декоратор @ensure внутри этого класса. После этого вы можете настроить проверку на своей виртуальной машине после получения элемента: this.validation = validation.on(this.item); или ваша служба может настроить проверку, когда она возвращает ваш элемент в вашу виртуальную машину и делает его неотъемлемой частью модели: item.validation = validation.on(item);

Вариант А является самым простым и, кажется, соответствует вашему опыту. Вариант b более удобен в обслуживании, поскольку правила проверки для вашей модели будут жить на модели, а не на модели представления. Однако, если вы выберете вариант b, вам, возможно, придется немного откорректировать свой HTML, чтобы убедиться, что появляются подсказки о проверке.

Используйте метод.on валидатора, чтобы применить ваши правила к свойствам объекта.

Пример ниже вызывается после того, как я получаю объект с именем stock, он проверяет, что количество не является пустым и является только числовым. Надеюсь это поможет...

let stock = {
  name: 'some name'
  minimumQuantity: '1'
};

applyRules() {
  ValidationRules
    .ensure((m: EditStock) => m.minimumQuantity)
    .displayName("Minimum Quantity")
    .required()
    .withMessage(`\${$displayName} cannot be blank.`)
    .matches( /^[0-9]*$/)
    .withMessage(`\${$displayName} must be numeric only.`)       

  .on(this.stock);
}
Другие вопросы по тегам