我通过实现CustomValueAccessor
接口在Angular 2中创建了一个简单的自定义组件,它工作正常。该组件中只有1个输入字段。例如邮政编码组件
<postcode label="Post Code" cssClass="form-control" formControlName="postcode"> </postcode>
现在,我想扩展这个示例并创建一个具有多个输入字段的地址组件,line1,line 2,line3,postcode和country。
我已经扩展了邮政编码示例以包含多个字段,我可以在屏幕上看到输入组件。但是,地址组件值未反映在主机表单中。
在这个方向上欣赏任何指针。
示例:
import { Component, OnInit, Input } from '@angular/core';
import { FormControl, FormGroup, ControlValueAccessor, FormBuilder, NG_VALUE_ACCESSOR, Validators } from '@angular/forms';
import { Subscription } from 'rxjs/Subscription';
@Component({
selector: 'address',
templateUrl: './address.component.html',
styleUrls: ['./address.component.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: CommonAddressComponent,
multi: true
}
]
})
export class CommonAddressComponent implements OnInit , ControlValueAccessor {
addressForm : FormGroup
ngOnInit() {
this.addressForm = this.formBuilder.group({
line_1: '',
line_2: '',
});
}
/*private addressForm = new FormControl()*/
private subscription: Subscription;
public disabled: any = false;
constructor(private formBuilder: FormBuilder) { }
//model to view
writeValue(value: any) {
console.log("value = " + value)
this.addressForm.setValue(value);
}
registerOnChange(fn: (value: any) => void) {
console.log("registerOnChange = " + fn)
this.addressForm.valueChanges.subscribe(fn);
}
registerOnTouched() {}
}
模板文件:
<div class="form-group" [formGroup]="addressForm">
<input class="form-control" type="text" formControlName="line_1" />
<input class="form-control" type="text" formControlName="line_2" />
</div>
主机表单组件文件:
import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup, Validators, FormBuilder} from '@angular/forms';
@Component({
selector: 'app-contacts',
templateUrl: './contacts.component.html',
styleUrls: ['./contacts.component.scss']
})
export class ContactsComponent implements OnInit {
contactsForm: FormGroup;
constructor(private fb: FormBuilder) {
this.createForm();
}
createForm() {
this.contactsForm = this.fb.group({
name: 'test', // <--- the FormControl called "name"
postcode: 'tester111', // <--- the FormControl called "name"
line_3: '111', // <--- the FormControl called "name"*/
addressForm: new FormGroup({
line_1: new FormControl('I am line 1', Validators.minLength(2)),
line_2: new FormControl('I am line 2')
}),
});
}
ngOnInit() {
}
}
主机表单组件模板文件:
<form [formGroup]="contactsForm">
<p>Form value: {{ contactsForm.value | json }}</p>
<p>Form status: {{ contactsForm.status | json }}</p>
<div class="form-group">
<label class="center-block">Name:
<input class="form-control" formControlName="name">
</label>
</div>
<div>
<postcode label="Post Code" cssClass="form-control" formControlName="postcode"> </postcode>
</div>
<div class="form-group">
<address-line cssClass="form-control" name="line3" label="line 3" elementName="line3"
elementID="line3" formControlName="line_3"> </address-line>
</div>
<!--<div [formGroup]="contactsForm.addressForm"> -->
<div >
<address formGroupName="addressForm"> </address>
</div>
</form>
答案 0 :(得分:2)
经过多次尝试,我能够在Angular工作中获得具有多个输入字段的自定义控件。代码如下:
具有多个输入字段的自定义组件
import { Component, OnInit, Input, ViewChild } from '@angular/core';
import { FormControl,NgForm, FormGroup, ControlValueAccessor, FormBuilder, NG_VALUE_ACCESSOR, Validators, NgModel } from '@angular/forms';
import { Subscription } from 'rxjs/Subscription';
@Component({
selector: 'address',
templateUrl: './address.component.html',
styleUrls: ['./address.component.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: AddressComponent,
multi: true
}
]
})
export class AddressComponent implements OnInit , ControlValueAccessor {
addressForm : FormGroup
@Input() label: string;
constructor(private formBuilder: FormBuilder) { }
ngOnInit() {
this.addressForm = this.formBuilder.group({
line1: '',
line2: '',
line3: '',
line4: '',
});
}
writeValue(value: any) {
if (value) {
this.addressForm.setValue(value);
}
}
registerOnChange(fn: (value: any) => void) {
console.log("registerOnChange = " + fn)
this.addressForm.valueChanges.subscribe(fn);
}
registerOnTouched() {}
}
自定义组件的模板
<div class="form-group" [formGroup]="addressForm">
<input type="text" name="line1" class="form-control" type="text" formControlName="line1" />
<input type="text" name="line2" class="form-control" type="text" formControlName="line2" />
<input type="text" name="line3" class="form-control" type="text" formControlName="line3" />
<input type="text" name="line4" class="form-control" type="text" formControlName="line4" />
</div>
主机或父组件类
从'@ angular / core'导入{Component}; 从'@ angular / forms'中导入{NgForm,Validators,FormControl,FormGroup};
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
pageForm: FormGroup = new FormGroup({
address: new FormGroup({
line1: new FormControl('',Validators.required),
line2: new FormControl('',Validators.required),
line3: new FormControl('',Validators.required),
line4: new FormControl('')
}),
})
}
<div class="container">
<form [formGroup]="pageForm">
<p>Form value: {{ pageForm.value | json }}</p>
<p>Form status: {{ pageForm.status | json }}</p>
<address label="Line 1" formControlName="address" > </address>
</form>
</div>
答案 1 :(得分:0)
请注意,主机或父组件类必须将“地址”字段声明为FormControl,而不是FormGroup:
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
pageForm: FormGroup = new FormGroup({
address: new FormControl({
line1: new FormControl('',Validators.required),
line2: new FormControl('',Validators.required),
line3: new FormControl('',Validators.required),
line4: new FormControl('')
}),
})
}