Aurelia Validation Gives Error: TypeError: Object.defineProperty called on non-object
Aurelia Validation Gives Error: TypeError: Object.defineProperty called on non-object
我正在尝试对 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 ERROR [app-router] TypeError:
Object.defineProperty called on non-object
at Function.defineProperty ()
at Function.29.Rules.set (rules.js:14)
at FluentEnsure.48.FluentEnsure.on (validation-rules.js:347)
at FluentRuleCustomizer.48.FluentRuleCustomizer.on (validation-rules.js:95)
at PersonDetail.app/components/people/person-detail.PersonDetail.bind
(person-detail.ts:27)
at View.bind (aurelia-templating.js:1400)
at Controller.bind (aurelia-templating.js:3394)
at View.bind (aurelia-templating.js:1406)
at Controller.bind (aurelia-templating.js:3394)
at Controller.automate (aurelia-templating.js:3339)
如果我将 ValidationRules 行更改为:
ValidationRules.ensure('currentPerson.LastName').minLength(3).required().withMessageKey('lastNameReq').on(this);
然后我不再收到错误,但验证也不起作用(this.controller.validate() returns 在我清空姓氏字段时有效)。这与 LStarky 在这里发现的一致:。但是,如果我实施他的解决方案,则会出现上述错误。
通常您在 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);
}
根据您的评论,您似乎没有在 parent/container 加载元素时设置当前人物。有几种解决方法:
- 您可以使用
if
绑定,它只会在附加了人物时创建人物自定义元素(详细信息部分)。 (在父级中:<person-detail if.bind="currentPerson"><person-detail>
)。 if
在结果为真时 add/remove 将元素实际绑定到 DOM 中,因此只有当 person 对象具有值时才会实例化和绑定视图模型
- 你可以观察
PersonDetail
class里面绑定的person对象,只有当它有一个非空值时才调用验证规则。这有点棘手,因为您应该只设置一次验证规则,但有时这是可行的方法。使用名为 currentPersonChanged(newVal, oldVal)
的函数,它会自动为您调用。
如果这不起作用,请告诉我!
上面的 view/view 模型对被用作页面中的自定义元素 - 它是主细节 window 的细节部分。这意味着当页面和自定义元素首次创建时,currentPerson 属性 是未定义的,所以我在 属性 上创建验证规则时遇到错误。
此外,因为每次更改主列表中的行时 currentPerson 都会更改,我发现每次发生这种情况时我都必须创建验证规则。
因此解决方案是使 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)
}
}
}
}
我正在尝试对 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 ERROR [app-router] TypeError: Object.defineProperty called on non-object at Function.defineProperty () at Function.29.Rules.set (rules.js:14) at FluentEnsure.48.FluentEnsure.on (validation-rules.js:347) at FluentRuleCustomizer.48.FluentRuleCustomizer.on (validation-rules.js:95) at PersonDetail.app/components/people/person-detail.PersonDetail.bind (person-detail.ts:27) at View.bind (aurelia-templating.js:1400) at Controller.bind (aurelia-templating.js:3394) at View.bind (aurelia-templating.js:1406) at Controller.bind (aurelia-templating.js:3394) at Controller.automate (aurelia-templating.js:3339)
如果我将 ValidationRules 行更改为:
ValidationRules.ensure('currentPerson.LastName').minLength(3).required().withMessageKey('lastNameReq').on(this);
然后我不再收到错误,但验证也不起作用(this.controller.validate() returns 在我清空姓氏字段时有效)。这与 LStarky 在这里发现的一致:
通常您在 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);
}
根据您的评论,您似乎没有在 parent/container 加载元素时设置当前人物。有几种解决方法:
- 您可以使用
if
绑定,它只会在附加了人物时创建人物自定义元素(详细信息部分)。 (在父级中:<person-detail if.bind="currentPerson"><person-detail>
)。if
在结果为真时 add/remove 将元素实际绑定到 DOM 中,因此只有当 person 对象具有值时才会实例化和绑定视图模型 - 你可以观察
PersonDetail
class里面绑定的person对象,只有当它有一个非空值时才调用验证规则。这有点棘手,因为您应该只设置一次验证规则,但有时这是可行的方法。使用名为currentPersonChanged(newVal, oldVal)
的函数,它会自动为您调用。
如果这不起作用,请告诉我!
上面的 view/view 模型对被用作页面中的自定义元素 - 它是主细节 window 的细节部分。这意味着当页面和自定义元素首次创建时,currentPerson 属性 是未定义的,所以我在 属性 上创建验证规则时遇到错误。
此外,因为每次更改主列表中的行时 currentPerson 都会更改,我发现每次发生这种情况时我都必须创建验证规则。
因此解决方案是使 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)
}
}
}
}