Angular FormGroup 可能不触发 valueChanges 的原因及解决方法

只有通过构造函数初始化的 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);
      });
    });
  }

你可能感兴趣的:(Angular FormGroup 可能不触发 valueChanges 的原因及解决方法)