Javascript Aurelia验证给出错误:TypeError:Object.defineProperty在非对象上调用
我试图在一个Aurelia组件上进行基本的Aurelia验证,但遇到了一个错误 类型脚本是:Javascript Aurelia验证给出错误:TypeError:Object.defineProperty在非对象上调用,javascript,validation,aurelia,Javascript,Validation,Aurelia,我试图在一个Aurelia组件上进行基本的Aurelia验证,但遇到了一个错误 类型脚本是: import { bindable, inject, NewInstance } from 'aurelia-framework'; import { HttpClient } from 'aurelia-fetch-client'; import { validationMessages, ValidationRules, ValidationController } from 'aurelia-va
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>
名字:
姓氏:
中间名:
性别:
出生日期:
流动电话:
电邮:
保存到数据库
-
${error.message}
运行此命令时,会出现以下错误:
aurelia logging console.js:47错误[app router]类型错误:
对非对象调用Object.defineProperty
at 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
(人员详情:ts:27)
at View.bind(aurelia templating.js:1400)
在Controller.bind(aurelia templating.js:3394)
at View.bind(aurelia templating.js:1406)
在Controller.bind(aurelia templating.js:3394)
at Controller.automation(aurelia templating.js:3339)
如果我将ValidationRules行更改为:
ValidationRules.sure('currentPerson.LastName').minLength(3).required().withMessageKey('lastNameReq')。在(此)上代码>
然后我不再得到错误,但验证也不起作用(当我清空姓氏字段时,this.controller.validate()返回valid)。这与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);
}
根据您的评论,在父级/容器加载元素时,您似乎没有设置当前人员。有几种方法可以解决这个问题:
您可以使用if
绑定,该绑定仅在附加了person时创建person自定义元素(详细信息部分)。(在父项中:
)<代码>如果
绑定在结果为真时实际将元素添加/删除到DOM中,那么视图模型将仅在person对象具有值时实例化和绑定
PersonDetail
类中查看绑定的person对象,并且仅在其具有非空值时调用验证规则。这有点棘手,因为您应该只设置一次验证规则,但有时这是一种方法。使用名为currentPersonChanged(newVal,oldVal)
的函数,它将自动为您调用如果不行,就告诉我 上面的视图/视图模型对被用作页面中的自定义元素-它是主详细信息窗口的详细信息部分。这意味着在第一次创建页面和自定义元素时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)
}
}
}
}
验证规则时,this.currentPerson
属性是否未定义。确保行运行?我可能是错的,纯粹是根据错误猜测。嗨@adiga是的,没错,它没有定义。我在下面提出了一个解决方案。您是否尝试过对Person
类本身而不是该类的每个实例应用ValidationRules
?类似这样:ValidationRules.sure('LastName').minLength(3).required().withMessageKey('lastNameReq')。在(Person)
上,我尝试了一下,但得到了一个typescript错误TS2693:'Person'只引用一个类型,但在这里被用作一个值。Aurelia文档说您应该能够做到这一点。好的-通过创建Person并导出类而不是接口并将其导入ts文件,成功地消除了该错误。但是,验证没有起作用!:-/你好。很抱歉,我应该提到我也在bind事件中尝试了它,但是我仍然得到相同的错误。在此方法中,此.currentPerson仍未定义。我同意你期望它在这一点上有一个值。上述组件用作母版/详细信息页面的详细信息部分,并且在母版部分中选择记录时设置currentPerson。我认为问题与这种设置有关。我会继续玩的。哦,我看你已经找到解决办法了!如果可以的话,我会尝试1,因为这是一种更好的方法。#1是一个很好的建议,但我认为最好的方法是对人的类型进行验证,正如下面的问题讨论的那样。不幸的是,我不能让它工作。我在上面回答,但你把它放在哪里取决于。如果person内部有另一个对象,以此类推,则需要该对象的自定义元素上的规则,而不是父对象上的规则。