注意-我在末尾包含了一个堆栈链接。
我的代码有问题,如果当前填充了另一个表单控件,我希望从本质上禁用该表单控件。例如,如果字段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();
}
});
我得到"超过最大调用堆栈大小"错误。也许有一种更好的方法可以用反应形式来做这件事,但我还没有遇到任何东西。我采用这种方法的部分原因是,一旦字段为空,它将用更少的代码轻松地重新启用其他字段。
Stacklitz链接如果你注释掉b和c的valueChanges,并且只有一个,你可以看到我想要的行为,但如果你再添加一个valueChanges,就会出现错误。
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
当您调用值更改"a"时,您会调用另一个值更改,依此类推,直到达到调用堆栈限制。
基本上完整的表单映射在模型上,因此无论何时启用/禁用任何控件,表单模型的属性都会更改。由于模型正在更改,所以valueChanges事件将被触发。
如果你使用新版本的angular,你可能可以使用
this.form.get('b'(.setValue(newValue,{onlySelf:true,emitEvent:false}(;