Angular 角度2-稍后在反应形式数组中进行设置验证

Angular 角度2-稍后在反应形式数组中进行设置验证,angular,typescript,Angular,Typescript,我通过以下方式正确构建表单数组: this.items.forEach(element => { (<FormArray>this.myFormFixtures.get('fixtures')).push(this.fBuilder.group({ id: [element.id], name: [element.name, Validator

我通过以下方式正确构建表单数组:

this.items.forEach(element => {
                    (<FormArray>this.myFormFixtures.get('fixtures')).push(this.fBuilder.group({
                        id: [element.id],
                        name: [element.name, Validators.required],
                        description: [element.description],
                        startDateTime: this.buildTimeDetails(element.startDateTime),
                        venueId: [element.venueId, Validators.required],
                        participants: this.buildParticipants(element.participants)
                    }));
                });
                this.myFormFixtures.valueChanges
                    .subscribe(formData => this.checkFixturesFormValidity(formData));
默认情况下,这两个ID是可选的。但我想将两个参与者ID FormControlName都设置为必需的,以防其中一个获得值

到目前为止,我的“checkFixturesFormValidity”函数看起来是这样的,但由于某些原因,没有设置验证:

checkFixturesFormValidity(formData)
    {
        console.log(formData);

        const control = <FormArray>this.myFormFixtures.controls['fixtures'];

        for (let i = 0; i < control.length; i++) {

            const participantsControl = (<FormArray>this.myFormFixtures.controls['fixtures']).at(i).get('participants') as FormArray;

                if ((((<any>this.myFormFixtures.controls['fixtures']).at(i).controls['participants'].at(0).get('id').value) != null) || (((<any>this.myFormFixtures.controls['fixtures']).at(i).controls['participants'].at(1).get('id').value) != null))
                {
                    (<any>this.myFormFixtures.controls['fixtures']).at(i).controls['participants'].at(0).get('id').setValidators([Validators.required]);
                    (<any>this.myFormFixtures.controls['fixtures']).at(i).controls['participants'].at(1).get('id').setValidators([Validators.required]);
                }


        }

    }
checkFixturesFormValidity(formData)
{
console.log(formData);
const control=this.myFormFixtures.controls['fixtures'];
for(设i=0;i
我已经在某种程度上缩短了所有这些长属性路径,因为在迭代中,我们可以传递例如您在
*ngFor
中命名的对象,因此在方法中,我们不需要从
this.myFormFixtures.controls开始。…

因此,我们在这里所做的是将更改事件设置为select。因为我们知道,当用户进行选择时,如果值不是
null
,我们将设置
Validators.required

因此,
t正文
的内容如下(缩短):



这些都是相当长的路径,所以我不打算尝试找出它们是否有问题;)但你可能需要打电话。如果没有帮助,请创建一个plunker来演示这个问题。我将查看如何创建plunker:)我调用了updateValueAndValidity(),但它不断使浏览器崩溃,说maxmium调用堆栈超出了范围,这可能是因为这一行:
.subscribe(formData=>this.checkFixturesFormValidity(formData))
checkFixturesFormValidity()
在表单值中发生任何事情时都会被调用,并且由于您在其中使用了
updateValueAndValidity()
,“更改发生”,这意味着订阅将再次启动,并继续进行,直到浏览器崩溃;)你应该考虑一个简单的<代码>更改<代码>事件来代替这个字段。我先试试看,如果不行,我就派一辆普朗克。谢谢你迄今为止的帮助:)没问题。如果没有其他错误,我认为
updateValueAndValidity
将解决您的问题。作为旁注,即使这是一个意见问题,我也开始依赖事件,而不是使用
valueChanges
,除非我有特定的原因。对于事件,您可以更严格地控制触发的内容和时间。当使用valueChanges时,您无法将其控制得很紧,而在性能方面,这可能会变得很重。即使只是在组件初始化时,
valueChanges
也会被触发x次,这通常是完全不必要的:)谢谢,这太棒了!如果我需要修改它,如果用户再次取消选择这两个下拉列表,那么最好的方法是什么?循环doSomething方法中的数组,如果数组中的所有值都为null,则清除验证器,否则设置验证器?在你看来,最好避免“价值变化”?在我对你的问题发表评论时,我解释了为什么我更喜欢变化事件。特别是在本例中,您注意到您在更改检测、
subscribe
和调用方法:)方面遇到了问题。至于您的另一个问题,这里有一种可能可以解决,如果两者都未选中,验证程序将被删除:
checkFixturesFormValidity(formData)
    {
        console.log(formData);

        const control = <FormArray>this.myFormFixtures.controls['fixtures'];

        for (let i = 0; i < control.length; i++) {

            const participantsControl = (<FormArray>this.myFormFixtures.controls['fixtures']).at(i).get('participants') as FormArray;

                if ((((<any>this.myFormFixtures.controls['fixtures']).at(i).controls['participants'].at(0).get('id').value) != null) || (((<any>this.myFormFixtures.controls['fixtures']).at(i).controls['participants'].at(1).get('id').value) != null))
                {
                    (<any>this.myFormFixtures.controls['fixtures']).at(i).controls['participants'].at(0).get('id').setValidators([Validators.required]);
                    (<any>this.myFormFixtures.controls['fixtures']).at(i).controls['participants'].at(1).get('id').setValidators([Validators.required]);
                }


        }

    }