Вопрос:

Попытка показать несколько сообщений <mat-error> с помощью matAutocomplete и matInput в реактивных формах (материал 2)

angular typescript angular-material2

2594 просмотра

1 ответ

382 Репутация автора

Я хочу отобразить пару сообщений об ошибках, используя mat-error. Я использую компоненты Angular Material 2 с реактивными формами. Я также использую errorStateMatcherдля контроля, когда появляется сообщение об ошибке. Это хорошо работает для встроенных валидаторов, как required. Тем не менее, для matAutocomplete я также хочу, когда No Matching Records are found(в основном, когда пользователь вводит что-то, чего нет в раскрывающемся списке).

htmlЧасть формы выглядит , как показано ниже

                   <mat-form-field>
                        <input matInput
                               [matAutocomplete]="insurerAuto"
                               formControlName="insurer"
                               [errorStateMatcher]="requiredErrorState"
                               (keydown)="PanelOptions($event, insurerAuto)"
                               placeholder="Insurer" required>
                        <mat-autocomplete #insurerAuto="matAutocomplete"
                                          [displayWith]="displayFn">
                            <mat-option *ngFor="let insurer of filteredInsuranceVendors|async"
                                        [value]="insurer">
                                {{ insurer.name }}
                            </mat-option>
                        </mat-autocomplete>
                        <mat-error>{{errorMsgs.requiredMsg}}</mat-error>
                    </mat-form-field>

Как видите, у меня есть mat-errorсообщение «обязательное поле». Но я хочу что-то вроде этого:

<mat-form-field>
                        <input matInput
                               [matAutocomplete]="insurerAuto"
                               formControlName="insurer"
                               [errorStateMatcher]="requiredErrorState"
                               (keydown)="PanelOptions($event, insurerAuto)"
                               placeholder="Insurer" required>
                        <mat-autocomplete #insurerAuto="matAutocomplete"
                                          [displayWith]="displayFn">
                            <mat-option *ngFor="let insurer of filteredInsuranceVendors|async"
                                        [value]="insurer">
                                {{ insurer.name }}
                            </mat-option>
                        </mat-autocomplete>
                        <mat-error *ngIf="policyForm.get('policyType').get('subType').hasError('required')">{{errorMsgs.requiredMsg}}</mat-error>
                        <mat-error *ngIf="(filteredInsuranceVendors|async)?.length === 0">No Matching records found!</mat-error>
                    </mat-form-field>

С двумя mat-errorтегами с *ngIfусловиями, контролирующими, когда показывать соответствующие сообщения об ошибках. Проблема, с которой я столкнулся, заключается filteredInsuranceVendorsв том, что Observableя использую ее async, и я не уверен, как я могу использовать ее для сравнения длины.

Блок кода компонента:

    /** Error when invalid control is dirty, touched, or submitted. */
export class RequiredErrorStateMatcher implements ErrorStateMatcher {
    isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
        const isSubmitted = form && form.submitted;
        return !!(control && control.invalid && (control.dirty || control.touched || isSubmitted));
    }
}

export const errorMessages: { [key: string]: string } = {
    requiredMsg: 'This field is required'
};

export class SomeComponent implements OnInit {
    requiredErrorState = new RequiredErrorStateMatcher();
    errorMsgs = errorMessages;
    filteredInsuranceVendors:  Observable<Array<object>>;

    filterInsuranceVendor(): void {
        const insurerControl = this.policyForm.get('insurerInfo.insurer');
        this.filteredInsuranceVendors = this.commonFilter(insurerControl, this.insuranceVendors);

    }

        commonFilter(control: AbstractControl, lst: Array<object>): Observable<any> {
        return control.valueChanges
            .map(lstObj => this.displayFn(lstObj))
            .map(ObjName =>
                ObjName ? this.utilityService.filterForAutocomplete(ObjName, lst) : lst.slice())
    }

}

Я хочу, чтобы моя функция errorStateMatcher включала оба условия, как показано ниже.

        /** Error when invalid control is dirty, touched, or submitted. */
export class RequiredErrorStateMatcher implements ErrorStateMatcher {
    isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
       if (this. filteredInsuranceVendors && !this. filteredInsuranceVendors.length) {
            return true;
        }
        const isSubmitted = form && form.submitted;
        return !!(control && control.invalid && (control.dirty || control.touched || isSubmitted));
    }
}

Одна из проблем заключается в том, что я не уверен, как с этим бороться, filteredInsuranceVendorsпоскольку это можно наблюдать. Я пытался преобразовать его в Array<object>, но я не смог использовать его errorStateMatcher.

Любой вклад будет высоко оценен. Спасибо!

Автор: mrsan22 Источник Размещён: 08.11.2017 10:50

Ответы (1)


0 плюса

167 Репутация автора

Я просто использую Validators.compose

this.form = this.fb.group({
field: ['', Validators.compose([Validators.required, Validators.pattern(...)])],
...
}
Автор: ali karimi Размещён: 09.12.2017 03:51
Вопросы из категории :
32x32