可重复使用的Angular组件如何授予其对ngForm的访问权限?

问题描述

我是Angular的新手,我正在尝试构建可重用的输入组件。目前,我的代码可以按预期工作,但是我需要我的输入组件才能访问ngForm Submit,以便它可以触发输入字段错误。这是下面的代码。

input.component.ts

import {
  Component,OnInit,Input,ViewChild,ElementRef,Self,} from '@angular/core';
import {
  ControlValueAccessor,Validator,AbstractControl,ValidatorFn,Validators,NgControl,} from '@angular/forms';

@Component({
  selector: 'app-input',templateUrl: './input.component.html',styleUrls: ['./input.component.scss'],})
export class InputComponent implements ControlValueAccessor,OnInit {
  @ViewChild('input') input: ElementRef;
  disabled;

  @Input() type = 'text';
  @Input() isRequired: boolean = false;
  @Input() pattern: string = null;
  @Input() label: string = null;
  @Input() placeholder: string;
  @Input() errorMsg: string;
  @Input() form: any = {};

  constructor(@Self() public controlDir: NgControl) {
    this.controlDir.valueAccessor = this;
  }
  log(val) {
    console.log(val);
  }

  setClasses(event,form) {
    console.log(form);
    let myClassess = {
      valid: event.valid && (event.touched || form.submitted),invalid: event.invalid && (event.touched || form.submitted),};
    return myClassess;
  }

  ngOnInit() {
    const control = this.controlDir.control;
    const validators: ValidatorFn[] = control.validator
      ? [control.validator]
      : [];
    if (this.isRequired) {
      validators.push(Validators.required);
    }
    if (this.pattern) {
      validators.push(Validators.pattern(this.pattern));
    }

    control.setValidators(validators);
    control.updateValueAndValidity();
  }

  onChange(event) {}

  onTouched() {}

  writeValue(obj: any): void {
    this.input.nativeElement.value = obj;
  }
  registerOnChange(fn: any): void {
    this.onChange = fn;
  }
  registerOnTouched(fn: any): void {
    this.onTouched = fn;
  }
  setDisabledState?(isDisabled: boolean): void {
    this.disabled = isDisabled;
  }

  validate(c: AbstractControl): { [key: string]: any } {
    const validators: ValidatorFn[] = [];
    if (this.isRequired) {
      validators.push(Validators.required);
    }
    if (this.pattern) {
      validators.push(Validators.pattern(this.pattern));
    }

    return validators;
  }
}

input.component.html

<div class="form-group">
  <label>{{ label }}</label>
  <input
    class="form-control"
    [type]="type"
    #input
    (input)="onChange($event.target.value)"
    (blur)="onTouched()"
    [disabled]="disabled"
    [ngClass]="setClasses(controlDir,form)"
  />
  <div
    class="text-danger"
    *ngIf="
      controlDir && !controlDir.control.valid && controlDir.control.touched
    "
  >
    {{ errorMsg }}
  </div>
</div>

form.component.ts

import { Component,OnInit } from '@angular/core';
import { NgForm } from '@angular/forms';

@Component({
  selector: 'app-form',templateUrl: './form.component.html',styleUrls: ['./form.component.scss'],})
export class FormComponent implements OnInit {
  name = 'hi';
  @Input() form: NgForm;
  constructor() {}

  log(v) {
    console.log(v);
  }

  ngOnInit(): void {}

  scrollToError(): void {
    const firstElementWithError: HTMLElement = document.querySelector(
      'form .ng-invalid'
    );
    window.scroll({
      top: this.getTopOffset(firstElementWithError),left: 0,behavior: 'smooth',});
  }

  getTopOffset(controlEl: HTMLElement): number {
    const labelOffset = 50;
    return controlEl.getBoundingClientRect().top + window.scrollY - labelOffset;
  }

  onSubmit(event) {
    if (event.valid) {
      console.log('submitted');
    }
    this.scrollToError();
  }
}

form.component.html

<form class="form-signin" (ngSubmit)="onSubmit(form)" #form="ngForm">
  <div class="text-center mb-4">
    <h1 class="h3 mb-3 font-weight-normal">Register Page</h1>
  </div>

  <app-input
    [isRequired]="true"
    [errorMsg]="'Please enter you name'"
    [label]="'Full Name'"
    ngModel
    name="name"
  ></app-input>

  <app-input
    [isRequired]="true"
    [errorMsg]="'Please enter valid email address'"
    [label]="'User Email'"
    [pattern]="'[A-Za-z0-9._%-]+@[A-Za-z0-9._%-]+\\.[a-z]{2,3}'"
    ngModel
    name="email"
    form="form"
  ></app-input>
  <div style="height: 1000px"></div>

  <button class="btn btn-lg btn-primary btn-block" type="submit">
    Sign in
  </button>
</form>
<div>{{ form.value | json }}</div>

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)