Проверка 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:&nbsp;</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>

введите здесь описание изображения


person si2030    schedule 20.01.2018    source источник


Ответы (1)


При загрузке существующего клиента с сервера вы устанавливаете свойство this.client как простой объект JSON. Он больше не будет экземпляром ClientDetails, и, следовательно, правила проверки не будут работать, поскольку они работают только с экземплярами ClientDetails.

Вам нужно будет создать новый экземпляр ClientDetails и заполнить его из объекта data, возвращенного fetch. Это можно сделать вручную, создав конструктор или метод сопоставления в ClientDetails, который принимает объект данных и сопоставляется с каждым свойством ClientDetails (this.clientId = data.clientId и т. д.).

В качестве альтернативы у вас может быть какая-то универсальная функция сопоставления, которая будет выполнять сопоставление по именам свойств. Я не очень хорошо знаком с TypeScript, но этот SO вопрос имеет много решений о том, как это сделать.

person Miroslav Popovic    schedule 20.01.2018
comment
Реализован вариант 4 упомянутого вопроса SO, и он сработал. - person si2030; 21.01.2018