Angular V11: NullInjectorError: нет поставщика для ControlContainer
У меня есть пользовательский ввод, сделанный в соответствии с этой статьей: medium.com: dont-reinvent-the-wheel .
Вот мой код, он в строгом режиме ▼
// input.component.ts
import { Component, Input, ViewChild } from '@angular/core';
import {
ControlContainer,
ControlValueAccessor,
FormControl,
FormControlDirective,
NG_VALUE_ACCESSOR
} from '@angular/forms';
import {
FloatLabelType,
MatFormFieldAppearance
} from '@angular/material/form-field';
@Component({
selector: 'app-input',
templateUrl: './input.component.html',
styleUrls: ['./input.component.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: InputComponent,
multi: true
}
]
})
export class InputComponent implements ControlValueAccessor {
isDisabled!: boolean;
@Input() isRequired!: boolean;
@Input() label!: string;
@Input() placeholder!: string;
@Input() readonly!: boolean;
@Input() appearance: MatFormFieldAppearance = 'fill';
@Input() floatLabel: FloatLabelType = 'auto';
@ViewChild(FormControlDirective, { static: true })
formControlDirective!: FormControlDirective;
@Input() formControl!: FormControl;
@Input() formControlName!: string;
get control(): FormControl {
return (
this.formControl ||
this.controlContainer.control?.get(this.formControlName)
);
}
constructor(private controlContainer: ControlContainer) {}
clearInput(): void {
this.control.setValue('');
}
registerOnTouched(fn: any): void {
this.formControlDirective.valueAccessor?.registerOnTouched(fn);
}
registerOnChange(fn: any): void {
this.formControlDirective.valueAccessor?.registerOnChange(fn);
}
writeValue(obj: any): void {
this.formControlDirective.valueAccessor?.writeValue(obj);
}
setDisabledState(disabled: boolean): void {
this.isDisabled = disabled;
}
}
<!-- input.component.html -->
<div class="custom-input">
<mat-form-field
[appearance]="appearance"
[floatLabel]="floatLabel"
class="custom-input__form-field"
>
<mat-label class="custom-input__label"
>{{ label }} <span *ngIf="isRequired && label">*</span></mat-label
>
<input
class="custom-input__value"
matInput
type="text"
[formControl]="$any(control)"
[placeholder]="placeholder"
[readonly]="readonly"
/>
<button
class="custom-input__clear-btn"
matSuffix
mat-icon-button
aria-label="Clear"
*ngIf="$any(control).value && !readonly"
(click)="clearInput()"
>
<mat-icon>close</mat-icon>
</button>
</mat-form-field>
</div>
Ошибка компилятора отсутствует, но браузер регистрирует эту ошибку ▼
ERROR Error: Uncaught (in promise): NullInjectorError: R3InjectorError(ClientsListModule)[ControlContainer ->
ControlContainer -> ControlContainer -> ControlContainer -> ControlContainer -> ControlContainer]:
NullInjectorError: No provider for ControlContainer!
NullInjectorError: R3InjectorError(ClientsListModule)[ControlContainer -> ControlContainer -> ControlContainer ->
ControlContainer -> ControlContainer -> ControlContainer]:
NullInjectorError: No provider for ControlContainer!
Я проверил аналогичные вопросы здесь Angular 5: «Нет поставщика для ControlContainer», а здесь нет поставщика для ControlContainer, и, согласно им, проблема заключается в том, что не импортируются как ReactiveFormsModule, так и FormsModule в соответствующий модуль, но я импортирую их, и все же вижу эту ошибку .
ОБНОВЛЕНИЕ 1: В компонентах
<app-input>
используется следующим образом ▼
1 ответ
Как кажется, вы используете
formControl
без
formGroup
в некоторых случаях, поэтому используйте
@Optional
декоратор иметь
controlContainer
ноль в этих случаях.
constructor(@Optional() private controlContainer: ControlContainer) {}