我正在尝试对Aurelia组件进行基本的Aurelia验证,但是收到错误。
打字稿是:
import { bindable, inject, NewInstance } from 'aurelia-framework';
import { HttpClient } from 'aurelia-fetch-client';
import { validationMessages, ValidationRules, ValidationController } from 'aurelia-validation';
@inject(HttpClient, NewInstance.of(ValidationController))
export class PersonDetail {
@bindable currentPerson: Person;
private httpClient: HttpClient;
public controller: ValidationController;
constructor(http: HttpClient, controller: ValidationController) {
this.httpClient = http;
this.controller = controller;
validationMessages['lastNameReq'] = 'You must enter a last name';
ValidationRules.ensure('LastName').minLength(3).required().withMessageKey('lastNameReq').on(this.currentPerson);
}
saveToDb() {
this.controller.validate()
.then(v => {
if (v.valid) {
// this.httpClient...(do stuff)
}
}
}
}
html是:
<template bindable="currentPerson">
<form submit.delegate="saveToDb()">
<p>First Name: <input type="text" class="form-control" value.bind="currentPerson.FirstName"></p>
<p>Last Name: <input type="text" class="form-control" value.bind="currentPerson.LastName & validate"></p>
<p>Middle Name: <input type="text" class="form-control" value.bind="currentPerson.MiddleName"></p>
<p>Gender: <input type="text" class="form-control" value.bind="currentPerson.Sex"></p>
<p>DOB: <input type="text" class="form-control" value.bind="person.DOB"></p>
<p>Mobile Phone: <input type="text" class="form-control" value.bind="currentPerson.MobilePhnNbr"></p>
<p>Email: <input type="text" class="form-control" value.bind="currentPerson.EmailAddr"></p>
<button type="submit" class="btn-primary">Save to Database</button>
<ul if.bind="controller.errors">
<li repeat.for="error of controller.errors">
${error.message}
</li>
</ul>
</form>
</template>
运行此操作我收到以下错误:
aurelia-logging-console.js:47错误[app-router] TypeError: 在非对象上调用Object.defineProperty 在Function.defineProperty() 在Function.29.Rules.set(rules.js:14) 在FluentEnsure.48.FluentEnsure.on(validation-rules.js:347) 在FluentRuleCustomizer.48.FluentRuleCustomizer.on(validation-rules.js:95) 在PersonDetail.app/components/people/person-detail.PersonDetail.bind (人次detail.ts:27) 在View.bind(aurelia-templating.js:1400) 在Controller.bind(aurelia-templating.js:3394) 在View.bind(aurelia-templating.js:1406) 在Controller.bind(aurelia-templating.js:3394) 在Controller.automate(aurelia-templating.js:3339)
如果我将ValidationRules行更改为:
ValidationRules.ensure('currentPerson.LastName').minLength(3).required().withMessageKey('lastNameReq').on(this);
然后我不再收到错误,但验证也不起作用(当我清空姓氏字段时,this.controller.validate()返回有效)。这符合LStarky在这里找到的内容:Aurelia Validation not working with object properties。但是,如果我实施他的解决方案,我会收到上述错误。
答案 0 :(得分:0)
通常,您可以使用bind()
方法设置验证规则,尤其是当您要验证的对象 - this.currentPerson
- 是@bindable
时,因为它不会在构造函数被调用时有一个值。
constructor(http: HttpClient, controller: ValidationController) {
this.httpClient = http;
this.controller = controller;
validationMessages['lastNameReq'] = 'You must enter a last name';
}
bind() {
ValidationRules.ensure('LastName').minLength(3).required().withMessageKey('lastNameReq').on(this.currentPerson);
}
根据您的评论,当父/容器加载元素时,您似乎没有设置当前人。有几种方法可以解决这个问题:
if
绑定,只有在附加了人员时才会创建人员自定义元素(详细信息部分)。 (在父母:<person-detail if.bind="currentPerson"><person-detail>
)。 if
绑定实际上在结果为true时将元素添加/删除到DOM中,因此只有在person对象具有值时才会实例化和绑定视图模型PersonDetail
类中查看绑定人对象,并且只有在具有非空值时才调用验证规则。这有点棘手,因为你应该只设置一次验证规则,但它有时候还是要走的路。使用名为currentPersonChanged(newVal, oldVal)
的函数,它将自动为您调用。如果这不起作用,请告诉我!
答案 1 :(得分:0)
上面的视图/视图模型对被用作页面中的自定义元素 - 它是主详细信息窗口的详细信息部分。这意味着在首次创建页面和自定义元素时,currentPerson属性未定义,因此在该属性上创建验证规则时出现错误。
此外,因为每次更改主列表中的行时currentTeerson都会更改,所以我发现每次发生这种情况时都必须创建验证规则。
因此,解决方案是使currentPerson可观察并在currentPersonChanged方法中设置验证规则。最终的代码如下:
import { bindable, inject, NewInstance, observable } from 'aurelia-framework';
import { HttpClient } from 'aurelia-fetch-client';
import { validationMessages, ValidationRules, ValidationController } from 'aurelia-validation';
@inject(HttpClient, NewInstance.of(ValidationController))
export class PersonDetail {
@bindable @observable currentPerson: Person;
private httpClient: HttpClient;
public controller: ValidationController;
constructor(http: HttpClient, controller: ValidationController) {
this.httpClient = http;
this.controller = controller;
validationMessages['lastNameReq'] = 'You must enter a last name';
}
currentPersonChanged() {
if (this.currentPerson) {
ValidationRules.ensure('LastName').minLength(3).required().withMessageKey('lastNameReq').on(this.currentPerson);
}
}
saveToDb() {
this.controller.validate()
.then(v => {
if (v.valid) {
// this.httpClient...(do stuff)
}
}
}
}