只有通过构造函数初始化的 FormControl 才能触发 valueChanges
/**
* 在接收到所有必须数据后再创建表单
* 此处不能先创建 FormGroup 再添加 FormControl,否则后续创建的 FormControl 无法触发 FormGroup 的 valueChanges 事件
*/
private _initFormGroup() {
combineLatest(
this.countryService.countries,
this.regionService.regions,
this.productService.companies,
this.productCatalogService.tree
).pipe(
map(r => ({ countries: r[0], regions: r[1], companies: r[2], catalogs: r[3] }))
).subscribe(rs => {
if (_.isNil(rs.regions) ||
_.isNil(rs.countries) ||
_.isNil(rs.catalogs) ||
_.isNil(rs.companies)) {
return;
}
// 针对 FormArray 只有在初始化时传入的 FormControl 才能出发 valueChanges 事件
const faCountries = new FormArray(rs.countries.map(c => new FormControl(false)));
const faRegions = new FormArray(rs.regions.map(r => new FormControl(false)));
const faCompanies = new FormArray(rs.companies.map(c => new FormControl(false)));
const faCatalogControls = [];
let catalogSequenceID = 0;
rs.catalogs.forEach(c => {
(c as any).sequenceID = catalogSequenceID++;
faCatalogControls.push(new FormControl(false));
forEachDescendant(c, tn => {
(tn as any).sequenceID = catalogSequenceID++;
faCatalogControls.push(new FormControl(false));
});
});
const faCatalogs = new FormArray(faCatalogControls);
const refinementsForm = this.formBuilder.group({
countries: faCountries,
regions: faRegions,
companies: faCompanies,
catalogs: faCatalogs,
price: new FormControl('', Validators.required),
time: new FormControl('', Validators.required)
});
this.refinementsForm = refinementsForm;
this.countries = rs.countries;
this.companies = rs.companies.map(c => ({ name: c }));
this.catalogs = rs.catalogs;
this.regions = rs.regions;
this.refinementsForm.valueChanges.pipe(debounce(() => interval(1000))).subscribe(f => {
f.countries = f.countries.map((c, i) => c === true ? this.countries[i].code : '').filter(c => c !== '');
f.regions = f.regions.map((r, i) => r === true ? this.regions[i].regionName : '').filter(r => r !== '');
f.companies = f.companies.map((c, i) => c === true ? this.companies[i].name : '').filter(c => c !== '');
const catalogs = [];
this.catalogs.forEach(c => {
const sequenceID = (c as any).sequenceID;
if (f.catalogs[sequenceID] === true) {
catalogs.push(c.value);
}
forEachDescendant(c, tn => {
const sid = (tn as any).sequenceID;
if (f.catalogs[sid] === true) {
catalogs.push(tn.value);
}
});
});
f.catalogs = catalogs;
this.valueChange.emit(f);
});
});
}