angular - 我怎样才能在 Angular 中解决同样的问题,而 ng-messages 在 AngularJS 中解决了?

标签 angular

在 AngularJS 中,有一个名为 ng-messages 的表单指令,它帮助我们做到这一点,以便不会同时显示所有表单错误。因此,例如,如果输入有 3 个错误:required、minlength、maxlength。然后只显示 required , required 有效后,再显示 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>

我们如何在 Angular 中以优雅的方式实现这一点?

最佳答案

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

下面我提供了一个例子(没有编译或运行它,但它应该给你足够的信息让你开始)。仅在触摸、脏污等情况下显示消息的逻辑可以很容易地添加到此。

用法

<validation-messages [for]="control">
  <validation-message name="required">This field is required</validation-message>
</validation-messages>

实现

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);
  }
}

关于angular - 我怎样才能在 Angular 中解决同样的问题,而 ng-messages 在 AngularJS 中解决了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42157675/

相关文章:

ios - Angular 8 - 如何在 iOS 中下载文件

angular - 异常 : Root segment cannot have matrix parameters

angular - Async beforeEach 在每个测试单元之前/之后完成

angular - 如何摆脱 Angular6 typescript 错误?

css - Angular 应用程序中的过渡动画在 EDGE 中不起作用

angular - karma 不断要求更多与测试组件无关的进口

html - Angular 7 组件 : how to detect a change by user interaction?

angular - 属性绑定(bind)与属性插值

css - 覆盖 Kendo UI CSS

angular - 在 Angular 6 中设置文件输入的值