Проблема CSS с Angular Material и вложенным полем mat-form-field: внутреннее поле mat-form-field в состоянии ошибки приводит к тому, что родитель выглядит в состоянии ошибки - PullRequest
0 голосов
/ 22 ноября 2018

Я пытаюсь разобраться с большой формой, создающей пользовательский компонент для каждого раздела, размещая всю логику и пользовательскую проверку в каждом пользовательском компоненте.По сути, каждый раздел является субформой, и каждый из них вносит свой вклад в процесс проверки большой формы.

Я также использую Angular Material, и мои пользовательские компоненты настраивают элемент управления полем формы реализуютинтерфейс MatFormField<T>, таким образом, я смогу использовать красивый внешний вид, чтобы показать ошибку и подсказку о компоненте в целом.

По этой причине я оборачиваю свой пользовательский компонент внутри<mat-form-field> и даже поля формы в шаблоне пользовательского компонента заключены в <mat-form-field>.

Но у меня проблема с этим решением и угловым материалом.Если поле в подформе недопустимо, <mat-error> для пользовательского компонента отображается правильно и даже <mat-error> для внутреннего поля формы отображается.Проблема также в том, что все остальные поля становятся красными, как будто они недействительны, но на самом деле это не так!

Вот пример: https://stackblitz.com/edit/angular-2h2fql?embed=1&file=src/app/app.component.ts

каждое поле обязательно для заполнения, просто попробуйте очистить одно из них или добавить новую строку, и даже все остальные поля станут красными.

Я думаю, что это просто CSS, потому что когда <mat-form-field> недопустим, класс сообщений <mat-error> отображается и класс mat-form-field-invalid применяется к элементу хоста <mat-form-field>, который поворачиваетсякрасным цветом недопустимое поле.

Мой вопрос: знает ли кто-нибудь, можно ли вручную отобразить <mat-error> или установить элемент управления пользовательской формы в состоянии ошибки, не применяя класс .mat-form-field-invalid к хосту?element?

Насколько я понимаю, этот класс связан с состоянием ошибки, как вы можете видеть здесь

https://github.com/angular/material2/blob/master/src/lib/form-field/form-field.ts#L120

, но я не могу найти элегантное решение дляпреодолеть эту проблему.

Я пытался применить инкапсуляцию вида ShadowDOM, но она не работает нормально.

Я просто не мог поместить свой пользовательский элемент управления формы в <mat-form-field>, и он будетработать нормально и <mat-error> будет отображаться, ноне в смысле дизайна материала.

Я ошибаюсь или это какая-то проблема с угловым материалом?

надеюсь, мое объяснение понятно, спасибо

1 Ответ

0 голосов
/ 23 ноября 2018

Я думаю, что вы можете запутаться в намеченной цели mat-form-field ... важно отметить особенность, mat-form-field против mat-form-fields

В этом документе "формаполе "относится к компоненту-оболочке <mat-form-field>, а" элемент управления полем формы "относится к компоненту, который <mat-form-field> оборачивает (например, input, textarea, select и т. д.)

https://material.angular.io/components/form-field/overview


Хотя это описание открыто для интерпретации ... конструкция оболочки поля формы должна была быть 1: 1 ..., что означает 1 оболочку, 1 элемент управления.

  • просмотрев все примеры стекаблиц для поля формы, вы увидите этот стандарт 1: 1.

https://material.angular.io/components/form-field/examples

Обернув несколько mat-form-fields в родительский элементmat-form-field Вы, по сути, превращаете их всех в один большой mat-form-field, который рассматривает все элементы управления как один элемент управления с точки зрения стилизации для errorState ... если один недействителен, все они недействительны, поскольку это один гигант form-field.


Примените следующую оболочку поля формы в вашем people-list.component.htmlи вы увидите, что проблема реплицируется в вашем примере OUTSIDE MAT FORM FIELD.

<div [formGroup]="form">
  <mat-form-field>
    <div formArrayName="rows" *ngFor="let p of rows.controls; let i=index">
        <div [formGroupName]="i" fxLayout="row" fxLayoutAlign="space-around center">

            <mat-form-field hintLabel="row number {{ i }}" class="full-width">
                <input matInput type="text" formControlName="name"/>
                <mat-hint align="end">Valid: {{ p.get('name').valid }}</mat-hint>
                <mat-error *ngIf="p.get('name').hasError('required')">required</mat-error>
            </mat-form-field>

            <mat-form-field class="full-width">
                <mat-select placeholder="Select state" formControlName="state">
                    <mat-option *ngFor="let state of stateList" [value]="state.abbreviation">
                        {{state.name}}
                    </mat-option>
                </mat-select>
                <mat-hint align="end">Valid: {{ p.get('state').valid }}</mat-hint>
                <mat-error *ngIf="p.get('state').hasError('required')">required</mat-error>
            </mat-form-field>

            <button class="glyphicon glyphicon-remove pull-right" *ngIf="rows.length > 0"
                  (click)="removeStep(i)">Remove</button>
            <br>
        </div>
    </div>
    <br>
    <button [disabled]="!rows.valid"
            (click)="addStep()"
            type="button"
            color="primary"
            *ngIf="rows.length < maxlength">
        <span translate>ADD</span>
    </button>
    </mat-form-field>
</div>

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

создать mat-form-field-underline класс в app.component.scss

.matFormFieldUnderline{
  bottom: 1.25em;
  background-color: rgba(0,0,0,.42);
  height: 1px;
  margin-top:5px;
}

Затем использовать его в своем HTML и повторить стиль mat-form-field

<h2>OUTSIDE MAT FORM FIELD</h2>
            <app-state-selector
                        name="people2"
                        [ngModel]="peopleList2"
                        #peopleRef2="ngModel"
                        required
                        maxlength=5
                ></app-state-selector>
                <div class="matFormFieldUnderline" [style.background-color]="peopleRef2.errors ? 'red' : null"></div>
                <div fxLayout>
                  <div fxFlex="70">
                   <mat-hint *ngIf="!peopleRef2.errors?.rows">Valid component: {{ peopleRef2.valid }}</mat-hint>
                   <mat-error *ngIf="peopleRef2.errors?.rows">Valid component: {{ peopleRef2.valid }}</mat-error>
                  </div>
                  <div fxFlex="30" fxLayoutAlign="end"> 
                    <mat-hint>{{peopleRef2.value?.length || 0}} rows</mat-hint>
                  </div>
                </div>  
                <mat-error *ngIf="peopleRef2.errors?.required">required</mat-error>
                <mat-error *ngIf="peopleRef2.errors?.maxlength">max 5 rows</mat-error>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...