Проверка Aurelia - Форма загружена данными из выборки - проверка оценивает полные поля как пустые
У меня есть форма, которую я успешно загружаю с данными из выборки. Если я затем нажму кнопку "Сохранить" в этой форме, Aurelia Validation оценит те текстовые поля формы, в которых есть данные, как пустые, и отобразит это как ошибку под кнопкой сохранения - рисунок ниже.
Проверка отлично работает в пустой форме, но для формы с загруженными значениями она выглядит так, как будто форма действует так, как будто она пустая.
Конечно, если в текстовом поле есть символы, набирая или загружая из выборки, он должен оценить это в контексте "требуется" и передать?
В настоящее время его нет, когда он загружен из выборки.
Код
Вот модель представления машинописного текста:
import { HttpClient } from "aurelia-fetch-client";
import { autoinject, inject, NewInstance, PLATFORM } from "aurelia-framework";
import { Router, activationStrategy } from "aurelia-router";
import {
ValidationControllerFactory,
ValidationController,
ValidationRules,
validateTrigger
} from "aurelia-validation";
import { BootstrapFormRenderer } from "../../../../services/bootstrapFormRenderer/bootstrapFormRenderer";
//import from '../../../../services/customValidationRules/customValidationRules'
import { AuthService } from "../../../../services/auth/auth-service"
@autoinject
export class Client {
controller: ValidationController;
client = new ClientDetails;
job: Job;
visits = Array();
hasClientId: boolean;
heading: string = "New Client";
headingIcon: string = "fa-user-plus";
username: string;
constructor(
private authService: AuthService,
private router: Router,
private controllerFactory: ValidationControllerFactory
) {
this.router = router;
this.controller = controllerFactory.createForCurrentScope();
this.controller.addRenderer(new BootstrapFormRenderer());
this.controller.addObject(this)
this.controller.addObject(this.client);
}
// Required to reload new instance.
determineActivationStrategy() {
return activationStrategy.replace; //replace the viewmodel with a new instance
// or activationStrategy.invokeLifecycle to invoke router lifecycle methods on the existing VM
// or activationStrategy.noChange to explicitly use the default behavior
}
activate(parms, routeConfig) {
this.hasClientId = parms.id;
if (this.hasClientId) {
const headers = this.authService.header();
fetch("/api/Client/edit/" + parms.id, {
method: "GET",
headers
})
.then(response => response.json())
.then(data => {
this.client = data
})
this.heading = "Edit Client"; // An id was submitted in the route so we change the heading as well.
this.headingIcon = "fa-pencil-square-o";
}
return null;
}
submitClient() {
console.log("gets Here");
console.log("this.controller.validate(): ", this.controller.validate());
//this.controller.validate();
if (this.controller.validate()) {
console.log("Hi!");
}
}
rowSelected(jobId: number) {
let job = this.client.jobs.filter(f => f.id === jobId);
if (job && job.length > 0) {
var jobVisits = job.map(j => { return j.jobVisits; })[0];
this.visits = jobVisits;
}
}
}
export class ClientDetails {
clientId: number;
clientNo: number;
company: boolean;
companyName: string;
abn: string;
isWarrantyCompany: boolean;
requiresPartsPayment: boolean;
clientFirstName: string;
clientLastName: string;
email: string;
mobilePhone: string;
phone: string;
notes: string;
address: AddressDetails;
jobs: Job[];
bankName: string;
bankBSB: string;
bankAccount: string;
active: boolean;
deActivated: string;
activity: boolean;
dateCreated: string;
dateUpdated: string;
creatorId: number;
creatorName: string;
}
class Job {
id: number;
agentJobNo: number;
jobNo: number;
jobType: string;
jobVisits: Visit[]
numberOfVisits: number;
status: string;
}
class Visit {
jobVisitId: number;
dateCreated: string;
visitDate: string;
startTime: string;
endTime: string;
}
class AddressDetails {
address1: string;
address2: string;
suburb: string;
postcode: string;
stateShortName: string;
addressLocationId: number;
}
// Validation Rules.
ValidationRules
.ensure((a: ClientDetails) => a.companyName).required()
.when((a: ClientDetails) => a.company === true)
.withMessage('Company name is required if client is a company.')
.ensure((a: ClientDetails) => a.clientLastName).required()
.ensure((a: ClientDetails) => a.mobilePhone).required()
.on(ClientDetails)
Выборка находится в функции активации и выбирается только при наличии идентификатора. Выборка загружает "клиента" с данными, которые возвращаются. Это работает, и у меня есть форма со всеми данными из выбранной выборки.
Однако если я нажму кнопку "Сохранить", даже если в двух полях "lastName" и "mobilePhone" есть значения, функция "submitClient()" сработает, и "this.controller.validate()" оценит эти поля как пустые,
Разве он не видит, что эти поля имеют значения в них? Есть что-то, чего я здесь не хватает?
Вот как у представления есть "lastName" - обратите внимание, что "& validate" присутствует.
<div class="col-md-6">
<div class="col-md-3">
<div class="form-group">
<label class="control-label pull-right" for="lastname">Last Name: </label>
</div>
</div>
<div class="col-md-9">
<div class="form-group">
<input type="text" value.bind="client.clientLastName & validate" class="form-control" id="lastname" placeholder="Last Name...">
</div>
</div>
</div>
1 ответ
При загрузке существующего клиента с сервера вы настраиваете this.client
свойство быть простым объектом JSON. Это больше не будет ClientDetails
и, следовательно, правила проверки не будут работать, так как они работают только на ClientDetails
экземпляров.
Вам нужно будет создать новый экземпляр ClientDetails
и заселить его из data
объект, возвращенный fetch
, Это можно сделать вручную, создав конструктор или метод отображения в ClientDetails
который принимает объект данных и сопоставляет с каждым ClientDetails
имущество (this.clientId = data.clientId
, так далее.).
В качестве альтернативы у вас может быть какая-то общая функция отображения, которая будет выполнять сопоставление по именам свойств. Я не очень знаком с TypeScript, но у этого ТАКОГО вопроса есть много решений о том, как это сделать.