注意-我在结尾处加入了stackblitz链接。
我的代码有问题,如果当前正在填充另一个formcontrol,则我希望实质上禁用formcontrol。例如,如果填充了字段A,则将禁用输入字段B和C。如果清除了字段A,则字段B和C将重新启用。这会在三个字段中按其各自的顺序发生,这意味着如果您填充B,则A和C将被禁用,等等。
this.SearchForm.get('a').valueChanges
.subscribe( ( value ) => {
if ( value ) {
this.SearchForm.get('b').disable();
this.SearchForm.get('c').disable();
} else {
this.SearchForm.get('b').enable();
this.SearchForm.get('c').enable();
}
});
如果我仅在一个字段上进行设置,则效果很好。但是,如果我将其更改为包括如下所述设置其他字段:
this.SearchForm.get('a').valueChanges
.subscribe( ( value ) => {
if ( value ) {
this.SearchForm.get('b').disable();
this.SearchForm.get('c').disable();
} else {
this.SearchForm.get('b').enable();
this.SearchForm.get('c').enable();
}
});
this.SearchForm.get('b').valueChanges
.subscribe( ( value ) => {
if ( value ) {
this.SearchForm.get('a').disable();
this.SearchForm.get('c').disable();
} else {
this.SearchForm.get('a').enable();
this.SearchForm.get('c').enable();
}
});
this.SearchForm.get('c').valueChanges
.subscribe( ( value ) => {
if ( value ) {
this.SearchForm.get('a').disable();
this.SearchForm.get('b').disable();
} else {
this.SearchForm.get('a').enable();
this.SearchForm.get('b').enable();
}
});
我收到“超出最大调用堆栈大小”错误。也许有一种更好的方法可以通过反应形式来做到这一点,但是我还没有遇到任何东西。之所以采用这种方法,部分原因是因为一旦该字段为空,它将以更少的代码轻松地重新启用其他字段。
Link of Stackblitz 如果将b和c的valueChanges注释掉并且只有一个,则可以看到我正在寻找的行为,但是,如果再添加一个额外的valuechanges,则会出现错误。
答案 0 :(得分:1)
disable()/ enable()方法有一个emitEvent选项:
disable(opts: { onlySelf?: boolean; emitEvent?: boolean; } = {}): void
enable(opts: { onlySelf?: boolean; emitEvent?: boolean; } = {}): void
https://angular.io/api/forms/AbstractControl
尝试传递{ emitEvent: false }
const disableEnableOptions = {emitEvent: false };
this.SearchForm.get('a').valueChanges
.subscribe( ( value ) => {
if ( value ) {
this.SearchForm.get('b').disable(disableEnableOptions);
this.SearchForm.get('c').disable(disableEnableOptions);
} else {
this.SearchForm.get('b').enable(disableEnableOptions);
this.SearchForm.get('c').enable(disableEnableOptions);
}
});
这应该阻止您的更改触发其他订阅者。您应该能够在其余的代码中实现这一点。
这是我为您带来的闪电战的分支:https://stackblitz.com/edit/angular-w5r29c
答案 1 :(得分:0)
将值更改称为“ a”时,将调用另一个值更改,依此类推,直到达到调用堆栈限制。
基本上完整的表单映射在模型上,因此,每当启用/禁用任何控件时,表单模型的属性都会更改。而且由于模型正在更改,因此将触发valueChanges事件。
如果您使用的是新版本的angular,则可以使用
this.form.get('b')。setValue(newValue,{onlySelf:true,发射事件:false});