在模型中使用 Aurelia 验证

Using Aurelia validation in model

这与 类似,但我们想在模型级别定义验证逻辑,但以下不显示验证消息。

user-model.js(不工作)

import {transient, inject} from 'aurelia-framework';
import {ensure} from 'aurelia-validation';

@transient()
export class UserModel {
  @ensure(function(it) { it.isNotEmpty().hasLengthBetween(3,10) })
  firstName = "";
  constructor() {
    this.firstName = "";
  }
}

user.js(不工作)

import {inject} from 'aurelia-framework';
import {Validation} from 'aurelia-validation';
import {UserModel} from 'models/user-model';

@inject(Validation, UserModel)
export class User {
  
  constructor(validation, userModel) {
    this.userModel = userModel;
    this.validation = validation.on(this);
  }
}

user.html(不工作)

<form role="form" validate.bind="validation">
  <div class="form-group">
    <label>First Name</label>
    <input type="text" validate="model.firstName" value.bind="model.firstName" class="form-control" >
  </div>
</form>

请注意 user.html 中使用了 validate="model.firstName",这使得验证有效,这意味着我看到 'has-success' class 被添加到表单组div 当用户输入有效时,但在输入无效时不显示消息。 但是,如果我在 user-model.js 之外取出验证逻辑并将其放入 user.js 中,如下所示,它工作得很好。

用户-model.js(工作)

import {transient, inject} from 'aurelia-framework';

@transient()
export class UserModel {
  constructor() {
    this.firstName = "";
  }
}

user.js(工作)

import {inject} from 'aurelia-framework';
import {Validation} from 'aurelia-validation';
import {UserModel} from 'models/user-model';

@inject(Validation, UserModel)
export class User {
  
  constructor(validation, userModel) {
    this.model = userModel;
    this.validation = validation.on(this)
      .ensure('model.firstName')
        .isNotEmpty()
        .hasLengthBetween(3,10);
  }
}

user.html(工作)

<form role="form" validate.bind="validation">
  <div class="form-group">
    <label>First Name</label>
    <input type="text" value.bind="model.firstName" class="form-control" >
  </div>
</form>

我们正在尝试在用户模型本身中定义验证逻辑,以便当我们需要在其他 UI 中使用它时,我们有一个集中的位置来验证它,而不是到处复制和粘贴逻辑。可能我做错了什么,但如果有人知道如何做到这一点,我们将不胜感激!

来自 aurelia-validation 文档,

As your viewmodels become more complex or if you start using binding converters, the binding path you used to set up the validation rules might be different than the binding path you used in your view, so you'll need to give the validate custom attribute some extra clues as to which elements should be matched against which validation rules. Consider this more complex example...

基本上,验证规则是针对 UserModel 中的 firstName 属性 创建的,但输入元素的绑定具有不同的绑定路径:value.bind="userModel.firstName" .因此,您需要在输入元素上添加一个 validate="firstName" 属性,以帮助 aurelia-validation 知道要为验证消息匹配哪个 HTML 元素。

这是您可以做到的 (with Plunkr)

用户-model.js

import {transient} from 'aurelia-framework';
import {ensure} from 'aurelia-validation';

@transient()
export class UserModel{
  @ensure(function(it) { it.isNotEmpty().hasLengthBetween(3,10) })
  firstName = "";

  constructor() {
    this.firstName = "";
  }
}

user.js

import {inject} from 'aurelia-framework';
import {Validation} from 'aurelia-validation';
import {UserModel} from 'user-model';

@inject(Validation, UserModel)
export class User {

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

}

user.html

<template>
  <form role="form" validate.bind="validation">
    <div class="form-group">
      <label>First Name</label>
      <input type="text" value.bind="userModel.firstName" validate="firstName" class="form-control">
    </div>
  </form>
</template>