如何在Angular中解决相同的问题,在AngularJS中解决了ng-messages?

Ale*_*lex 18 angular

在AngularJS中有一个名为ng-messages的表单指令,它帮助我们实现它,以便不会同时显示所有表单错误.因此,例如,如果输入有3个错误:required,minlength,maxlength.然后只需要显示,在需要后有效,然后显示minlength.如果没有ng-messages,我们需要做一些非常复杂和丑陋的逻辑,以便只显示必需而不显示其余部分,同时还要考虑只有在窗体控件也脏/触摸且无效时才会显示错误.

在AngularJS中,这将是:

<div ng-messages="form.username.$error" ng-if="form.username.$touched || form.username.$dirty">
    <div ng-message="required">Please enter a username.</div>
    <div ng-message="minlength">Username must be at least 3 characters.</div>
    <div ng-message="maxlength">Username can't exceed 30 characters.</div>
</div>
Run Code Online (Sandbox Code Playgroud)

我们怎样才能以优雅的方式在Angular中实现这一目标?

Dav*_*ots 20

有关可用于此目的的库,请参阅我的其他答案.这个答案的其余部分用于制作您自己的组件.

下面我提供一个例子(没有编译或运行它,但它应该给你足够的信息来开始).只有在触摸,弄脏等时才显示消息的逻辑可以很容易地添加到此.

用法

<validation-messages [for]="control">
  <validation-message name="required">This field is required</validation-message>
</validation-messages>
Run Code Online (Sandbox Code Playgroud)

履行

import { Component, OnInit, ContentChildren, QueryList, Input, OnDestroy } from '@angular/core';
import { FormControl } from '@angular/forms';
import { Subscription } from 'rxjs';

@Component({
  selector: 'validation-messages',
  template: '<ng-content></ng-content>'
})
export class ValidationMessagesComponent implements OnInit, OnDestroy {
  @Input() for: FormControl;
  @ContentChildren(ValidationMessageComponent) messageComponents: QueryList<ValidationMessageComponent>;

  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: '<div *ngIf="show"><ng-content></ng-content></div>'
})
export class ValidationMessageComponent {
  @Input() name: string;
  show: boolean = false;

  showsErrorIncludedIn(errors: string[]): boolean {
    return errors.some(error => error === this.name);
  }
}
Run Code Online (Sandbox Code Playgroud)