将验证 class 添加到 angular 6 模板驱动表单中的父元素

Add validation class to parent element in angular 6 template driven form

概览:

我正在尝试找到一种将 class 添加到 inputs 父元素的好方法

我目前有这个代码:

<p [ngClass]="{'error' : prop.invalid && (prop.dirty || prop.touched) }"> <label>Prop Label</label> <input type="text" [(ngModel)]="model.prop" #prop="ngModel" required /> </p>

效果很好!

问题:

我希望能够以更通用的方式进行,即

注意:我没有使用反应形式

您可以将自定义属性指令添加到 <p> 元素以检查其子 <input> 有效性。

关于您在问题中提到的问题:

  • using a directive to set the parent class:使用Renderer2class到add/removeerrorclass到<p>元素

  • (can't seem to find how to pass prop.invalid to it?):您将通过使用 @ContentChild 获得对 <input> 的引用,通过 NgModel class 找到它.

  • setting the parent element to receive the classes at a global level instead of the input: 不知道是什么问题,看起来像第一个。如果需要,请在此答案中添加评论。


Live Stackblitz DEMO

这些是您需要进行的更改:

HTML:

<p requiredValidator>
    <label>Prop Label</label>
  <br>
  <input type="text" [(ngModel)]="model.prop" #prop="ngModel" required />
</p>

指令:

import { Directive, ElementRef, Renderer2, ViewChild, ContentChild, AfterContentInit } from '@angular/core';
import { NgModel } from '@angular/forms';

@Directive({
  selector: '[requiredValidator]'
})
export class RequiredValidatorDirective implements AfterContentInit {
  element: ElementRef;
  renderer: Renderer2;
  @ContentChild(NgModel) input: NgModel;

  constructor(element: ElementRef, renderer: Renderer2) {
    this.element = element;
    this.renderer = renderer;
  }

  ngAfterContentInit() {
    this.input.valueChanges.subscribe(() => {
      if (this.input.invalid  && (this.input.dirty || this.input.touched)) {
        this.addErrorClass();
      } else {
        this.removeErrorClass();
      }
    })
  }

  addErrorClass(): void {
    this.renderer.addClass(this.element.nativeElement, 'error');
  }

  removeErrorClass(): void {
    this.renderer.removeClass(this.element.nativeElement, 'error');
  }
}