没有 ControlContainer 提供者,也没有 ControlContainer 提供者
Posted
技术标签:
【中文标题】没有 ControlContainer 提供者,也没有 ControlContainer 提供者【英文标题】:No provider for ControlContainer and No provider for ControlContainer 【发布时间】:2017-08-13 20:50:59 【问题描述】:我正在使用 Angular2 开发一个应用程序。 我正在尝试在我的应用程序中使用 Reactive Forms,但遇到了一些错误:
第一个错误是关于 NgControl 如下:
没有 NgControl 的提供者 ("
div class="col-md-8" [错误->]输入 class="表单控制" id="productNameId" "): ProductEditComponent@16:24
第二个错误是关于ControlContainer的,如下:
没有 ControlContainer 的提供者 (" div [错误->]div formArrayName="tags">
div class="行">
按钮 cl"):
Htmm 文件如下:
<div class="panel panel-primary">
<div class="panel-heading">
pageTitle
</div>
<div class="panel-body">
<form class="form-horizontal"
novalidate
(ngSubmit)="saveProduct()"
formGroup="productForm" >
<fieldset>
<div class="form-group"
[ngClass]="'has-error': displayMessage.productName ">
<label class="col-md-2 control-label" for="productNameId">Product Name</label>
<div class="col-md-8">
<input class="form-control"
id="productNameId"
type="text"
placeholder="Name (required)"
formControlName="productName" />
<span class="help-block" *ngIf="displayMessage.productName">
displayMessage.productName
</span>
</div>
</div>
<div formArrayName="tags">
<div class="row">
<button class="col-md-offset-1 col-md-1 btn btn-default"
type="button"
(click)="addTag()">Add Tag
</button>
</div>
<div class="form-group"
*ngFor="let tag of tags.controls; let i=index" >
<label class="col-md-2 control-label" [attr.for]="i">Tag</label>
<div class="col-md-8">
<input class="form-control"
[id]="i"
type="text"
placeholder="Tag"
formControlName="i" />
</div>
</div>
</div>
<!--more piece of code here -->
我的组件文件如下:
import Component, OnInit, AfterViewInit, OnDestroy, ViewChildren, ElementRef from '@angular/core';
import FormBuilder, FormGroup, FormControl, FormArray, Validators, FormControlName,NgForm from '@angular/forms';
import ActivatedRoute, Router from '@angular/router';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/observable/fromEvent';
import 'rxjs/add/observable/merge';
import Observable from 'rxjs/Observable';
import Subscription from 'rxjs/Subscription';
import IProduct from './product';
import ProductService from './product.service';
import NumberValidators from '../shared/number.validator';
import GenericValidator from '../shared/generic-validator';
@Component(
templateUrl: './product-edit.component.html'
)
export class ProductEditComponent implements OnInit, AfterViewInit, OnDestroy
@ViewChildren(FormControlName, read: ElementRef ) formInputElements: ElementRef[];
pageTitle: string = 'Product Edit';
errorMessage: string;
productForm: FormGroup;
product: IProduct;
private sub: Subscription;
// Use with the generic validation message class
displayMessage: [key: string]: string = ;
private validationMessages: [key: string]: [key: string]: string ;
private genericValidator: GenericValidator;
get tags(): FormArray
return <FormArray>this.productForm.get('tags');
constructor(private fb: FormBuilder,
private route: ActivatedRoute,
private router: Router,
private productService: ProductService)
// Defines all of the validation messages for the form.
// These could instead be retrieved from a file or database.
this.validationMessages =
productName:
required: 'Product name is required.',
minlength: 'Product name must be at least three characters.',
maxlength: 'Product name cannot exceed 50 characters.'
,
productCode:
required: 'Product code is required.'
,
starRating:
range: 'Rate the product between 1 (lowest) and 5 (highest).'
;
// Define an instance of the validator for use with this form,
// passing in this form's set of validation messages.
this.genericValidator = new GenericValidator(this.validationMessages);
ngOnInit(): void
this.productForm = this.fb.group(
productName: ['', [Validators.required,
Validators.minLength(3),
Validators.maxLength(50)]],
productCode: ['', Validators.required],
starRating: ['', NumberValidators.range(1, 5)],
tags: this.fb.array([]),
description: ''
);
// Read the product Id from the route parameter
this.sub = this.route.params.subscribe(
params =>
let id = +params['id'];
this.getProduct(id);
);
ngOnDestroy(): void
this.sub.unsubscribe();
ngAfterViewInit(): void
// Watch for the blur event from any input element on the form.
let controlBlurs: Observable<any>[] = this.formInputElements
.map((formControl: ElementRef) => Observable.fromEvent(formControl.nativeElement, 'blur'));
// Merge the blur event observable with the valueChanges observable
Observable.merge(this.productForm.valueChanges, ...controlBlurs).debounceTime(800).subscribe(value =>
this.displayMessage = this.genericValidator.processMessages(this.productForm);
);
addTag(): void
this.tags.push(new FormControl());
getProduct(id: number): void
this.productService.getProduct(id)
.subscribe(
(product: IProduct) => this.onProductRetrieved(product),
(error: any) => this.errorMessage = <any>error
);
onProductRetrieved(product: IProduct): void
if (this.productForm)
this.productForm.reset();
this.product = product;
if (this.product.id === 0)
this.pageTitle = 'Add Product';
else
this.pageTitle = `Edit Product: $this.product.productName`;
// Update the data on the form
this.productForm.patchValue(
productName: this.product.productName,
productCode: this.product.productCode,
starRating: this.product.starRating,
description: this.product.description
);
this.productForm.setControl('tags', this.fb.array(this.product.tags || []));
deleteProduct(): void
if (this.product.id === 0)
// Don't delete, it was never saved.
this.onSaveComplete();
else
if (confirm(`Really delete the product: $this.product.productName?`))
this.productService.deleteProduct(this.product.id)
.subscribe(
() => this.onSaveComplete(),
(error: any) => this.errorMessage = <any>error
);
saveProduct(): void
if (this.productForm.dirty && this.productForm.valid)
// Copy the form values over the product object values
let p = Object.assign(, this.product, this.productForm.value);
this.productService.saveProduct(p)
.subscribe(
() => this.onSaveComplete(),
(error: any) => this.errorMessage = <any>error
);
else if (!this.productForm.dirty)
this.onSaveComplete();
onSaveComplete(): void
// Reset the form to clear the flags
this.productForm.reset();
this.router.navigate(['/products']);
我试图解决这个问题超过 2 天,但我仍然没有解决方案。我在 *** 中看到了许多其他答案,但没有一个能解决我的问题。
【问题讨论】:
您是否在主应用程序模块或其他适当的模块中正确导入了 FormModule 和 ReactiveFormsModule? @R.Richards 是的,你是对的。我发现在导入和导出该组件的模块中 FormModule 和 ReactiveFormsModule 丢失了。非常感谢 No provider for ControlContainer - Angular 5的可能重复 【参考方案1】:从 app.module.ts 文件中的 @angular/forms 导入 Forms Module 和 ReactiveFormsModule
【讨论】:
如果这是 tab1.module.ts 中的选项卡式应用程序导入以上是关于没有 ControlContainer 提供者,也没有 ControlContainer 提供者的主要内容,如果未能解决你的问题,请参考以下文章
Angular 9“没有提供ControlContainer的提供者” VSCode错误,带有嵌套的Form Builder表单组