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

时间:2017-08-01 15:35:38

标签: javascript validation aurelia aurelia-validation

我正在尝试对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。但是,如果我实施他的解决方案,我会收到上述错误。

2 个答案:

答案 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);
}

根据您的评论,当父/容器加载元素时,您似乎没有设置当前人。有几种方法可以解决这个问题:

  1. 您可以使用if绑定,只有在附加了人员时才会创建人员自定义元素(详细信息部分)。 (在父母:<person-detail if.bind="currentPerson"><person-detail>)。 if绑定实际上在结果为true时将元素添加/删除到DOM中,因此只有在person对象具有值时才会实例化和绑定视图模型
  2. 您可以在PersonDetail类中查看绑定人对象,并且只有在具有非空值时才调用验证规则。这有点棘手,因为你应该只设置一次验证规则,但它有时候还是要走的路。使用名为currentPersonChanged(newVal, oldVal)的函数,它将自动为您调用。
  3. 如果这不起作用,请告诉我!

答案 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)
                }
             }
        }
}