How can I solve the same issue in Angular, that ng-messages solved in AngularJS?

前端 未结 3 1530
盖世英雄少女心
盖世英雄少女心 2021-02-12 13:44

In AngularJS there was a form directive named ng-messages which helped us to make it so that not all form errors showed at the same time. So that for example if an input has 3 e

3条回答
  •  遇见更好的自我
    2021-02-12 14:01

    See my other answer for a library you could use for this purpose. The remainder of this answer goes into making your own components.

    Below I supply an example (didn't compile or run it, but it should give you enough information to get going). The logic for only showing messages when touched, dirty, etc can be added to this easily.

    Usage

    
      This field is required
    
    

    Implementation

    import { Component, OnInit, ContentChildren, QueryList, Input, OnDestroy } from '@angular/core';
    import { FormControl } from '@angular/forms';
    import { Subscription } from 'rxjs';
    
    @Component({
      selector: 'validation-messages',
      template: ''
    })
    export class ValidationMessagesComponent implements OnInit, OnDestroy {
      @Input() for: FormControl;
      @ContentChildren(ValidationMessageComponent) messageComponents: QueryList;
    
      private statusChangesSubscription: Subscription;
    
      ngOnInit() {
        this.statusChangesSubscription = this.for.statusChanges.subscribe(x => {
          this.messageComponents.forEach(messageComponent => messageComponent.show = false);
    
          if (this.for.invalid) {
            let firstErrorMessageComponent = this.messageComponents.find(messageComponent => {
              return messageComponent.showsErrorIncludedIn(Object.keys(this.for.errors));
            });
    
            firstErrorMessageComponent.show = true;
          }
        });
      }
    
      ngOnDestroy() {
        this.statusChangesSubscription.unsubscribe();
      }
    }
    
    
    @Component({
      selector: 'validation-message',
      template: '
    ' }) export class ValidationMessageComponent { @Input() name: string; show: boolean = false; showsErrorIncludedIn(errors: string[]): boolean { return errors.some(error => error === this.name); } }

提交回复
热议问题