Angular 2+ 笔记 - 表单 Form

参考 Angular 4 修仙之路

set form error

Angular 自定义表单

Angular 修仙之路 自定义表单

reusable form

自定义表单组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
@Component({
selector: 'app-pizza-size-picker',
templateUrl: './pizza-size-picker.component.html',
styleUrls: ['./pizza-size-picker.component.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => PizzaSizePickerComponent),
multi: true
}
]
})

export class PizzaSizePickerComponent implements ControlValueAccessor {
pizzaSize: PizzaSizeEnum;
PizzaSizeEnum = PizzaSizeEnum;
propagateChange = (value: PizzaSizeEnum) => {};

constructor() { }

changeSize(size: PizzaSizeEnum) {
this.pizzaSize = size;
this.propagateChange(size); //把值返回到 form control
}

writeValue(value: PizzaSizeEnum) {
// 每当 form control 改变他的值的时候会调用 writeValue
this.pizzaSize = value;
}

registerOnChange(fn) {
// 每当我们返回值到 form control 的时候需要靠这个方法来实现
this.propagateChange = fn;
}

registerOnTouched() {}
}

创建嵌套表单:

第一我们要创建一个完整的formGroup

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
...
// 父级组件里创建 form
this.form = this.fb.group({
selectedPizza: null,
pizzas: this.fb.array([]),
customerDetails: this.fb.group({
firstName: [null, Validators.required],
lastName: [null, Validators.required],
phoneNumber: [null, Validators.required],
address: this.fb.group({
street: [null, Validators.required],
houseNum: [null, Validators.required],
city: [null, Validators.required],
floor: [null, Validators.required],
})
})
}, {
validator: this.pizzaValidatorsService.formValidator()
});
...

1
2
3
4
5
<div class="row">
<div class="col-md-12">
<app-customer-details [group]="form.get('customerDetails')"></app-customer-details>
</div>
</div>

子组件接受父级的 formGroup 然后正常使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Component({
selector: 'app-customer-details',
templateUrl: './customer-details.component.html',
styleUrls: ['./customer-details.component.scss']
})
export class CustomerDetailsComponent implements OnInit {

// 接收form group
@Input() group: FormGroup;
constructor() { }

ngOnInit() {
}
}
1
2
3
4
<div class="CustomerDetails" [formGroup]="group">
<input formControlName="firstName" />
...
</div>