Вы можете добавить пользовательскую директиву атрибута к элементу <p>
, которая будет проверять его дочернюю <input>
достоверность.
Относительно проблем, которые вы упомянули в своем вопросе:
using a directive to set the parent class
: используйте Renderer2
класс для добавления / удаления error
класса в <p>
элемент
(can't seem to find how to pass prop.invalid to it?)
: вы получите ссылку на <input>
с помощью @ContentChild
, найдя ее по классу NgModel
.
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');
}
}