【问题标题】:Aurelia validation nor working when data is pre-populated in the form在表单中预填充数据时,Aurelia 验证不起作用
【发布时间】:2018-03-29 17:52:48
【问题描述】:

我无法在其视图模型的激活方法中对已绑定数据的编辑模型视图进行验证。

我有一个 created.ts,它适用于具有相同字段的对象。该文件具有几乎相同的代码 - 例外是由于这是一个创建文件,因此不需要将数据加载到其中。在这种情况下,验证工作正常。

如果我注释加载编辑模型视图数据的代码 - 在 activate 方法中 - 验证工作正常。

不用说我是 SPA、Aurelia 和 TypeScript 的新手,需要一些帮助!!

下面是edit.ts中的代码

import { ContactRepository } from "./contactRepository";
import { autoinject } from "aurelia-framework";
import { ContactForEditDto } from "./contactForEditDto";
import { json } from "aurelia-fetch-client";
import { inject, NewInstance } from "aurelia-dependency-injection";
import { ValidationRules, ValidationControllerFactory, validateTrigger, 
Validator } from "aurelia-validation";


@autoinject
export class Edit {

public saveStatusMessage: string;
public isSaved: number = -1;
private controller = null;
private validator = null;
public canSave: boolean = false;

constructor(public contactForEdit: ContactForEditDto, private repository: 
ContactRepository, private controllerFactory: ValidationControllerFactory,
public contactFullName: string, validator: Validator) {

console.log("starting edit controller");

this.controller = controllerFactory.createForCurrentScope(validator);
this.controller.validateTrigger = validateTrigger.changeOrBlur;
this.validator = validator;
this.controller.subscribe(event => this.validateWhole());

ValidationRules

  .ensure((c: ContactForEditDto) => c.contactFirstName)
  .displayName("First Name")
  .required().withMessage("\${$displayName} cannot be empty.")
  .maxLength(50).withMessage("\${$displayName} cannot have more than 50 characters.")

  .ensure((c: ContactForEditDto) => c.contactLastName)
  .displayName("Last Name")
  .required().withMessage("\${$displayName} cannot be empty.")
  .maxLength(50).withMessage("\${$displayName} cannot have more than 50 characters.")


  .ensure((c: ContactForEditDto) => c.contactEmailAddress)
  .displayName("Email Address")
  //.required().withMessage("\${$displayName} cannot be empty.")
  .email().withMessage("\${$displayName} needs to be in a correct email address format.")
  .maxLength(50).withMessage("\${$displayName} cannot have more than 50 characters.")

  .ensure((c: ContactForEditDto) => c.contactPhoneNumber)
  .displayName("Phone Number")
  .required().withMessage("\${$displayName} cannot be empty.")
  .maxLength(12).withMessage("\${$displayName} cannot have more than 12 characters.")
  .matches(/\d{3}-\d{3}-\d{4}/).withMessage("'${$value}' is not a valid \${$displayName}. Please enter a phone in the format xxx-xxx-xxxx")

  .on(ContactForEditDto);

}

// source https://www.jujens.eu/posts/en/2017/Jan/24/aurelia-validation/ 
workaround 3
validateWhole() {
this.validator.validateObject(this.contactForEdit)
  .then(results => this.canSave = results.every(result => result.valid));
}

// Returning data from here because I can return a promise
// and let the router know when i have retrieved my initial data.

// Activate receives a params object as defined in the route.

activate(params) {
console.log("ACTIVATE ON EDIT PARAMS:" + params);
this.repository
  .getById(params.id)
  .then(data => {
    console.log(data);
    this.contactForEdit = data;
    this.contactFullName = this.contactForEdit.contactLastName + ", " + 
  this.contactForEdit.contactFirstName; // This needs to come from a method 
  in 
  contact.
  });
  }

  edit() {

this.saveStatusMessage = "";
this.isSaved = -1;

// This will be an edit
if (this.contactForEdit.contactId >= 1) {

  this.repository
    .update(this.contactForEdit)
    .then(response => {
      if (((response.status == 201) || (response.status == 204))
        && (response.ok == true)) {
        this.isSaved = 1;
        this.saveStatusMessage = "Successfully saved the contact";
      }
      else {
        this.isSaved = 0;
        //response.json().then(json => this.retVal = json);

        //TODO: get more details about the error.
        if (response.status == 400) {
          this.saveStatusMessage = "Unable to save the contact. Please make sure that you entered correct values for every field and try again.";
        }
        else {
          this.saveStatusMessage = "Unable to save the contact.";
        }
      }
    });
}

}

clearContactFields() {
this.contactForEdit = new ContactForEditDto(-1, "", "", "", "");
}


}

下面是edit.html中的代码

<template>
<form id="editContact" submit.delegate="edit()">
<!-- placeholder for status messages. If equal to 1 display it. If equals to 
-1 or 1 hide this.-->
<div id="successStatusMessage" class.bind="isSaved == 1 ? 'visible' : 
'hidden'">
  <div id="divSuccessMessage" class="alert alert-success">
    <a href="#" class="close" data-dismiss="alert">&times;</a>
    <!--<span class="glyphicon glyphicon glyphicon-ok" aria-hidden="true">
</span> TODO: How to get the glyphicon working? -->
    <span class="sr-only"> Success:</span> ${saveStatusMessage}
  </div>
</div>
<!-- placeholder for status messages.  If equal to 0 is in error, so dislay error message. if equals to -1 or 1 hide this.-->
<div id="errorStatusMessage" class.bind="isSaved == 0 ? 'visible' : 'hidden'">
  <!-- placeholder for status messages. -->
  <div id="divErrorMessage" class="alert alert-danger">
    <a href="#" class="close" data-dismiss="alert">&times;</a>
    <!-- <span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>  TODO:  class="glyphicon glyphicon-exclamation-sign" how to get these in here for class?   -->
    <span class="sr-only"> Error:</span> ${saveStatusMessage}
  </div>
</div>

<div class="panel panel-default">

  <div class="panel-heading">
    <div class="panel-title">
      <!--<div if.bind="isCreate">
        "Create a Contact"
      </div>

      <div if.bind="!isCreate">
        Edit ${contactForEdit.contactFirstName}
      </div>-->
      ${ "Edit " + contactFullName }
    </div>
  </div>

  <div class="panel-body">
    <div class="form-horizontal">

      <div class="form-group" validation-errors.bind="editFirstNameErrors"
           class.bind="editFirstNameErrors.length ? 'has-error' : ''">

        <label class="control-label col-md-2">First Name: </label>
        <div class="col-md-10">
          <input type="text"
                 placeholder="First Name"
                 class="form-control"
                 value.bind="contactForEdit.contactFirstName & validate" required /> <!-- NO ${} !!!-->

          <span class="help-block" repeat.for="editErrorInfo of editFirstNameErrors">
            ${editErrorInfo.error.message}
          </span>
        </div>

      </div>
      <div class="form-group" validation-errors.bind="editLastNameErrors"
           class.bind="editLastNameErrors.length ? 'has-error' : ''">
        <label class="control-label col-md-2">Last Name: </label>
        <div class="col-md-10">
          <input type="text"
                 placeholder="Last Name"
                 class="form-control"
                 value.bind="contactForEdit.contactLastName & validate" required /> <!-- NO ${} !!!-->
          <span class="help-block" repeat.for="editErrorInfo of editLastNameErrors">
            ${editErrorInfo.error.message}
          </span>
        </div>
      </div>

      <div class="form-group" validation-errors.bind="emailErrors"
           class.bind="editEmailErrors.length ? 'has-error' : ''">
        <label for="emailAddress" class="control-label col-md-2">Email: </label>
        <div class="col-md-10">
          <input id="emailAddress"
                 type="text"
                 placeholder="Email Address (format: email@domain.com)"
                 class="form-control"
                 value.bind="contactForEdit.contactEmailAddress & validate" /> <!-- NO ${} !!!-->
          <span class="help-block" repeat.for="editErrorInfo of editEmailErrors">
            ${editErrorInfo.error.message}
          </span>
        </div>
      </div>

      <div class="form-group" validation-errors.bind="editPhoneErrors"
           class.bind="editPhoneErrors.length ? 'has-error' : ''">
        <label class="control-label col-md-2">Phone: </label>
        <div class="col-md-10">
          <input type="text"
                 placeholder="Phone Number (format: xxx-xxx-xxxx)"
                 class="form-control"
                 value.bind="contactForEdit.contactPhoneNumber & validate" required /> <!-- NO ${} !!!-->
          <span class="help-block" repeat.for="editErrorInfo of editPhoneErrors">
            ${editErrorInfo.error.message}
          </span>
        </div>
      </div>

      <button type="submit" class="btn btn-default ${canSave ? '' : 'disabled'}">
        <!-- Look at click.dependent when there are child with buttons calling this.-->
        Save
      </button>
      <!-- AA-10-17-17 - replaced with errors per input field. <ul for.bind="controller.errors">
        <li repeat.for="error of controller.errors" style="color:red">
          ${error.message}
        </li>
      </ul>-->
    </div>
  </div>
</div>
</form>
<div>
  <a route-href="route: home"
     class="btn btn-default">
    Back to list
  </a>

</div>
</template>

【问题讨论】:

    标签: validation typescript edit aurelia


    【解决方案1】:

    我希望是因为这段代码: .getById(params.id) .then(data => { console.log(data); this.contactForEdit = data;

    您的验证针对的是 ContactForEditDto 对象,但我猜您的存储库正在返回一个转换为 ContactForEditDto 的 JSON 对象,因此它实际上根本不是一个类。 尝试类似的东西 console.log(data); this.contactForEdit = new ContactForEditDto(data.id, data.firstname ..etc..); 要么 console.log(data); this.contactForEdit = Object.assign(new ContactForEditDto(), data);

    【讨论】:

    • 感谢一百万的精彩回答。在浪费了 2 天的时间挖掘互联网之后,幸运的是我终于偶然发现了这里。只是想知道为什么这没有被标记为已接受。
    【解决方案2】:

    我们刚刚遇到了类似的问题,并通过在将远程数据分配给本地字段后设置验证来解决它。在您的代码中,您将在 this.contactForEdit = data; 之后设置验证规则

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-04
      • 2018-12-10
      相关资源
      最近更新 更多