Angular 2 错误:找不到具有未指定名称属性的控件 - 组件内的组件



我必须创建一个表单,并且我想更清楚组件

形式的主要思想是:

表单组件 |>字段组件 |> 表单的输入组件

所以我有PartnerFormComponent:

目录:

<form [formGroup]="partnerForm" (ngSubmit)="save()">
<!--<legal-information
[(partner)]="partner" [(partnerConfiguration)]="partnerConfiguration" ></legal-information>-->
<combo-billing-entity [(formGroup)]="partnerForm"       [(partner)]="partner" [(partnerConfiguration)]="partnerConfiguration"></combo-billing-entity>
<div class="buttons_form">
<button class="save_button_form" type="submit" [disabled]="!partnerForm.valid">
Add
</button>
<a class="btn-floating btn-large waves-effect waves-light green"
routerLink="/partners">
<i class="material-icons">Cancel</i>
</a>
</div>
</form>

和 ts:

@Component({
selector: 'partner-form',
templateUrl: './partner-form.component.html',
styleUrls: ['./partner-form.component.css'],
entryComponents:[LegalInformationComponent]
})
export class PartnerFormComponent implements OnInit {

private partnerForm: FormGroup;
title: string;
partner: Partner = new Partner();
partnerConfiguration: PartnerConfiguration = new PartnerConfiguration();
constructor(
private router: Router,
private route: ActivatedRoute,
private partnerService: PartnerService
) {  }

ngOnInit() {
var id = this.route.params.subscribe(params => {
var id = params['id'];
if (!id)
return;
.....
});
}

然后从组件我有 html 组合:

<div class="components_situation">
<div class="field_form_title">
{{title}} <span class="is_required_form" [hidden]="!isRequired">*</span>
</div>
<div [formGroup]="formGroup" >
<select id="billingEntity" [(ngModel)]="partnerConfiguration.fakeBillingEntity"
formControlName="billingEntity"
[class.invalid]="form.controls['billingEntity'].touched && !form.controls['billingEntity'].valid"
>
<option disabled hidden [value]="selectUndefinedOptionValue">-- select --</option>
<option *ngFor="let obj of billingEntities" [value]="obj.value" >{{obj.name}}</option>
</select>
</div>
<div class="some_explanation_form_field">{{someExplanation}}</div>
</div>

和 TS:

import {Component, Input, OnInit} from "@angular/core";
import {CommonFieldFormComponent} from "../../common-field-form-component";
import {BillingService} from "../../../../../../services/billing/billing.service";
import {BillingEntitity} from "../../../../../../model/billing_entity";
import {FormBuilder, FormGroup, Validators} from "@angular/forms";
@Component({
selector: 'combo-billing-entity',
templateUrl: './combo-billing-entity.component.html'
})
export class ComboBillingEntityComponent extends CommonFieldFormComponent implements OnInit {
private selectUndefinedOptionValue:any;
billingEntities:BillingEntitity[] = [];
@Input()
private formGroup:FormGroup;

constructor(private billingService: BillingService, private formBuilder:FormBuilder)
{
super();
this.isRequired=true;
this.title="Billing Entity";
this.someExplanation="Identifies entity responsible for billing invoice";
this.formGroup = this.formBuilder.group({
billingEntity :['', Validators.required]
});
}

但毕竟我有这个错误:

组合计费实体组件.html:5 错误:找不到具有未指定名称属性的控件 在_throwError (forms.es5.js:1852( at setUpControl (forms.es5.js:1760( at FormGroupDirective.webpackJsonp.../../../forms/@angular/forms.es5.js.FormGroupDirective.addControl (forms.es5.js:4733( at FormControlName.webpackJsonp.../../../forms/@angular/forms.es5.js.FormControlName._setUpControl (forms.es5.js:5321( at FormControlName.webpackJsonp.../../../forms/@angular/forms.es5.js.FormControlName.ngOnChanges (forms.es5.js:5239( at checkAndUpdateDirectiveInline (core.es5.js:10831( at checkAndUpdateNodeInline (core.es5.js:12330( at checkAndUpdateNode (core.es5.js:12269( at debugCheckAndUpdateNode (core.es5.js:13130( at debugCheckDirectivesFn (core.es5.js:13071(

知道如何将输入绑定到主表单..我做错了什么?

您的表单中有很多问题。您正在尝试在输入字段中使用双向绑定,例如[(formGroup)]="partnerForm"但是您没有使用@Output来实际触发双向绑定,因此您没有正确使用它。

表单对象确实是一个对象,对象在 JS 中是可变的,并通过引用传递。有时这不是可取的行为,但在这种情况下,我们希望在嵌套组件的情况下这样做。因此,无论您对子组件中的字段执行什么操作,父组件都会知道,因此您实际上不需要双向绑定。

其次,请避免以反应形式使用[(ngModel)]。我注意到可能会出现奇怪的行为,这是可以理解的,因为我们有两个绑定,到 ngModel 变量,另一个是表单控制变量。请改用表单控件,并从模板中删除所有 ngModel。您可以为表单控件设置值,这基本上将起到双向绑定的作用,因为您也可以随时从 TS 访问表单控件值。所以[(ngModel)]

在父级中构建整个表单,然后将表单组传递给子表单组,或者将嵌套表单组本地传递给子表单组。所以在你的父母中,你实际上想要构建表单:

this.partnerForm = this.fb.group({
billingEntity: ['hey I am initial value']
})

上面你可以将初始值设置为billingEntity,或者如果您需要在其他时候手动设置默认值,您可以通过以下方式做到这一点:this.partnerForm.get('billingEntity').setValue(...)

我们现在将此表格传递给孩子:

<combo-billing-entity [partnerForm]="partnerForm"></combo-billing-entity>

在孩子中,我们将其注册为Input

@Input() formGroup: FormGroup;

然后我们可以使用它,例如:

<div [formGroup]="partnerForm">
<input formControlName="billingEntity" />
</div>

我看到您正在尝试在那里使用[(ngModel)],但如前所述,您可以删除它并改用表单控件。该值很好地存储在formGroup.get('billingEntity').value中,如前所述,如果您需要在某个时候设置值,则可以这样做。但是您的所有表单值都很好地存储在表单对象中,即partnerForm.value.

下面是一个简单的演示:http://plnkr.co/edit/AuidEMaaURsBPfDP8k0Q?p=preview

我建议你阅读嵌套表单,这个很好入门:嵌套模型驱动表单

您的组件必须实现ControlValueAccessor并注册它是一个多依赖项。Pascal Precht有一篇关于Angular自定义表单控件的非常好的博客文章。

简而言之,在通过定义函数writeValueregisterOnChangeregisterOnTouched来实现ControlValueAccessor之后,您必须提供现有值,以便 Angular 可以知道您正在尝试将其用作表单控件。

@Component({
// ...
providers: [
{ 
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => ComboBillingEntityComponent),
multi: true,
}
],
// ...
})
class ComboBillingEntityComponent implements ControlValueAccessor {
// ...
}

在此之后,您可以在模板中的<combo-billing-entity>标签上使用formControlName

<combo-billing-entity formControlName="billingInfo"></combo-billing-entity>

最新更新