Javascript Aurelia验证给出错误:TypeError:Object.defineProperty在非对象上调用

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

我试图在一个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>

名字:

姓氏:

中间名:

性别:

出生日期:

流动电话:

电邮:

保存到数据库
  • ${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内部有另一个对象,以此类推,则需要该对象的自定义元素上的规则,而不是父对象上的规则。