Как использовать 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);
}