2015-05-28 6 views
2

Я использую Aurelia-проверку и моя проверка работает нормально, если я использую переменные, но мне нужно, чтобы проверить свойство объекта, а не переменный:Как использовать 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!"; 
      }) 
     } 
    ); 
    } 
    } 

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

ответ

4

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

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

Варианта а: заменить обеспечить декоратор с беглым API «обеспечить» метод, это поддерживает «вложенное» или «комплекс» связывание путей, такие как:

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);

Вариант a самый простой и, похоже, соответствует вашему опыту. Вариант b более удобен в обслуживании, так как правила проверки для вашей модели будут жить на модели, а не на модели представления. Однако, если вы идете с опцией b, you might have to adjust your HTML a bit to make sure validation hints appear.

+0

Можете ли вы описать класс 'option b'? Предлагаете ли вы создать второй класс для экземпляра 'item'? – chovy

+0

@chovy ах, я утверждал, что элемент был классом. Поскольку вы получаете его от службы, это, вероятно, JSON, и в этом случае вы не можете использовать декоратор @ -ensure. Вы все равно можете создать репозиторий, который обертывает вашу службу, выполняет вызов, а затем добавляет проверку на элемент с помощью свободного API проверки. –

1

Используйте метод .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); 
}