【问题标题】:How to display only single validation error at a time如何一次只显示一个验证错误
【发布时间】:2016-07-26 09:07:35
【问题描述】:

我有这段代码在我的表单上显示错误

<input [ngFormControl]="form1.controls['thing']" type="text" id="thing" #thing="ngForm">
<div *ngIf='thing.dirty && !thing.valid'>
    <div class="err" *ngIf='thing.errors.required'>
        Thing is required.
    </div >
    <div class="err" *ngIf='thing.errors.invalid'>
        Thing is invalid.
    </div >
</div>

但如果thing 有两个错误,则会显示两个错误。 假设我的输入有5 validators,那么5 divs 会出现,这不是很好。 如何一次只显示一个error div

【问题讨论】:

    标签: validation angular angular2-forms


    【解决方案1】:
    <input [ngFormControl]="form1.controls['thing']" type="text" id="thing" #thing="ngForm">
    <div *ngIf='thing.dirty && !thing.valid'>
        <div class="err" *ngIf='thing.errors.required'>
            Thing is required.
        </div >
        <div class="err" *ngIf='!thing.errors.required && thing.errors.ivalid'>
            Thing is invalid.
        </div >
    </div>
    

    您可以创建一个可重用的组件来显示错误,这样您就不需要一次又一次地重复此代码。

    【讨论】:

      【解决方案2】:

      Angular2 在后台检查控件的状态并做出相应的反应。因此,如果您不想一次进行更多验证,则可以合乎逻辑地使用 AND(&amp;&amp;) 或/和 OR(||) 或/和 @ 987654323@ 运营商。

      【讨论】:

        【解决方案3】:

        您可以创建一个自定义管道来获取验证器的错误对象的第一个元素:

        @Pipe({
          name: 'first'
        })
        export class FirstKeyPipe {
          transform(obj) {
            var keys = Object.keys(obj);
            if (keys && keys.length>0) {
              return keys[0];
            }
            return null;
          }
        }
        

        这样你就可以只显示一个错误:

        @Component({
          selector: 'my-app',
          template: `
            <form>
              <input [ngFormControl]="form.controls.input1">
              <div *ngIf="form.controls.input1.errors">
                <div *ngIf="(form.controls.input1.errors | first)==='required'">
                  Required
                </div>
                <div *ngIf="(form.controls.input1.errors | first)==='custom'">
                  Custom
                </div>
              </div>
            </form>
          `,
          pipes: [ FirstKeyPipe ]
        })
        export class MyFormComponent {
          constructor(private fb:FormBuilder) {
            this.form = fb.group({
              input1: ['', Validators.compose([Validators.required, customValidator])]
            });
          }
        }
        

        看到这个 plunkr:https://plnkr.co/edit/c0CqOGuzvFHHh5K4XNnA?p=preview

        注意:与 Günter 同意创建一个可用的组件 ;-) 有关详细信息,请参阅本文:

        【讨论】:

        • 您可以将其与NgSwitch 结合使用以稍微清理一下。此外,firstKey 可能是管道的更具描述性的名称。
        【解决方案4】:

        您可以创建一个Custom Pipe 来检查第一个错误是否等于指定的错误:

        自定义管道

        import { Pipe, PipeTransform } from '@angular/core';
        
        @Pipe({
          name: 'equals'
        })
        
        export class Equals implements PipeTransform {
        
          transform(errors: any, error: any, args?: any): any {
            if (!errors)
              return false;
        
            const array = Object.keys(errors);
            if (array && array.length > 0)
              return errors[array[0]] === error;
        
            return false;
          }
        }
        

        您可以有很多错误 div,但只会显示一个错误:

        // input is form.controls.input1
        <div *ngIf="input.errors | equals:input.errors.required">Required</div>
        <div *ngIf="input.errors | equals:input.errors.maxlength">MaxLength</div>
        <div *ngIf="input.errors | equals:input.errors.pattern">Pattern</div>
        

        【讨论】:

          【解决方案5】:

          如果您的错误消息块有一致的标记,那么您可以使用 css 仅显示第一条消息并隐藏其余消息:

          css

          .message-block .error-message {
            // Hidden by default
            display: none;
          }
          .message-block .error-message:first-child {
            display: block;
          }
          

          标记

          <div class="message-block">
            <span class="error-message" *ngIf="myForm.get('email').hasError('required')">
              Email is required (first-child of message block is displayed)
            </span>
            <span class="error-message" *ngIf="myForm.get('email').hasError('email')">
              Invalid email format (error message hidden by default)
            </span>
          </div>
          

          【讨论】:

          • 可能是最好的解决方案,它允许选择女巫错误是更重要的显示。
          • 虽然这可行,但这意味着您必须对模板中的所有验证检查进行硬编码。
          • .message-block .error-message:not(:first-child) { display: none; }。这样您就不必重写 CSS。
          【解决方案6】:

          这很有效,您不必像上面的@Joes 回答那样在模板中对验证进行硬编码。

          Template:
              <input id="password" placeholder="Password" type="password" formControlName="password" [(ngModel)]="password"  [ngClass]="{'invalid-input': !formUserDetails.get('password').valid && formUserDetails.get('password').touched}">
                    <div class="validation-container">
                      <ng-container *ngFor="let validation of userValidationMessages.password">
                        <div class="invalid-message" *ngIf="formUserDetails.get('password').hasError(validation.type) && formUserDetails.get('password').touched">
                          {{validation.message}}
                        </div>
                      </ng-container>
                    </div>
          
          CSS:
              .validation-container div {
                display: none;
              }
          
              .validation-container div:first-child {
                display: block;
              }
          

          【讨论】:

            猜你喜欢
            • 2018-09-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-05-09
            • 1970-01-01
            • 2012-03-07
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多