Angular:超过了调用堆栈的最大大小,有多个值Changes



注意-我在末尾包含了一个堆栈链接。

我的代码有问题,如果当前填充了另一个表单控件,我希望从本质上禁用该表单控件。例如,如果字段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}(;

相关内容

最新更新