我订阅了Angular反应形式的valueChanges事件。我需要对用户输入做出反应以防止或纠正他的输入,我尝试了几种方法,但没有人能按预期工作。订阅时出现Maximum call stack size exceeded
错误。
const controlArray = <FormArray> this.formArray.get('items');
this.formArray.get('items').valueChanges.subscribe(val => {
val.forEach(s => {
controlArray.controls.forEach(control => {
const con = control.get('symbol');
if (con.value === s.symbol) {
con.setValue(s.symbol.toUpperCase());
}
});
});
});
在这种情况下,我只想将每个字母输入更改为大写。我怎样才能做到这一点?还是有比每次键盘事件重复更少的方法更简单的方法?
我也尝试放置(change)="function(value)"
,但是只有在键盘:/
enter
时才会调用
答案 0 :(得分:1)
有一种更简单的方法可以实现此目的。使用input
指令。假设您有一个对象book
,并且您想在用户输入文本时将其字段title
设置为大写。
HTML模板
<input id="book-title" name="book-title" (input)="book.title = book.title.toUpperCase();"/>
答案 1 :(得分:1)
超出了最大调用堆栈大小,这是因为您发现自己陷入了无限循环,而观看时您更改的值要比观察者再次调用,它会更改该值,并再次调用观察者,一次又一次地更改值。
由于原生的patchValue方法,您可以做的是不发出观察者内部的事件:
this.myCustomForm.patchValue({
fieldSimbol: this.myCustomForm.value.fieldSimbol.toUpperCase()
}, { emitEvent: false })
然后您可以将其包含在通用的buildForm函数中
buildForm() {
//...FormControls
this.myForm= new FormGroup({
fieldSimbol: new FormControl('', Validators.required)
});
//..ValidationMessages
this.validationMessages = {
'fieldSimbol': [
{ type: 'required', message: 'Please fill this field' }
]
}
//..observe value change
this.myForm.valueChanges.subscribe((data) => {
//..other stuff
//..some controls
//..what you probably need
this.myCustomForm.patchValue({
fieldSimbol: this.myCustomForm.value.fieldSimbol.toUpperCase()
}, { emitEvent: false })
});
}