angualr2 使用valuechanges导致 maximum call stack size exceeded

说明

FormArray创建的table,需要动态的根据值改变计算求和,涉及到两个问题,记录一下自己是怎么解决的

问题1:怎么给每一个FormControl绑定valueChanges

  • 第一步:FormControl工厂函数
    demoFormControl(item) {
        return this.fb.group({
            id: [{ value: item.id ? item.id : '', disabled: false }],
            demo1: [{ value: item.demo1 , disabled: false }],
            demo2: [{ value: '' , disabled: false }]],
            demoSum: [{ value: '' , disabled: false }]],
                })
            }
  • 绑定valueChanges到每一个FormControl
    // 这个是创建的FormArray对象
    demoFrom: FormArray;
    // 以下是创建过程
    for (const item of this.hiredScoresList) {
        const items = this.demoFormControl(item);
        this.demoFrom.push(items);
        items.valueChanges.subscribe(x => {})
    }

问题2:如何防止赋值出现maximum call stack size exceeded

  • 错误做法
    // 这个是创建的FormArray对象
    demoFrom: FormArray;
    // 以下是创建过程
    for (const item of this.hiredScoresList) {
        const items = this.demoFormControl(item);
        this.demoFrom.push(items);
        items.valueChanges.subscribe(x => {
            items.patchValue({
                  demoSum: x.demo1 + x.demo2
             })
        })
    }
  • 正确做法

如果不加上emitEvent: false,那么每次赋值就会触发valueChanges,陷入死循环导致内存溢出,emitEvent: false将不再触发后续

    // 这个是创建的FormArray对象
    demoFrom: FormArray;
    // 以下是创建过程
    for (const item of this.hiredScoresList) {
        const items = this.demoFormControl(item);
        this.demoFrom.push(items);
        items.valueChanges.subscribe(x => {
            items.patchValue({
                  demoSum: x.demo1 + x.demo2
             }, { emitEvent: false })
        })
    }