Angular 无法通过 [(ngModel)] 获取输入值,当被 JavaScript 更改时
Angular can't get input value by [(ngModel)], when changed by JavaScript
我已经创建了一个自定义输入 formControl
,所以我需要通过 [(ngModel)]:
get/set 它的值
import { Component, Injector, OnInit, forwardRef } from '@angular/core';
import { ControlValueAccessor, FormControl, NG_VALUE_ACCESSOR, FormGroup } from '@angular/forms';
@Component({
selector: 'time-picker',
template:
`<input type="text" class="clockpicker" [formControl]="selectedTime" />`,
providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => TimePickerComponent),
multi: true,
}]
})
export class TimePickerComponent implements OnInit, ControlValueAccessor {
selectedTime = new FormControl('');
constructor() { }
ngAfterViewInit() {
this.scriptLoader.load(
'assets/clockpicker/clockpicker.js'
);
}
writeValue(obj: any): void {
if (this.selectedTime) {
this.selectedTime.setValue(obj);
}
}
registerOnChange(fn: any): void {
this.selectedTime.valueChanges.subscribe(fn);
}
registerOnTouched(fn: any): void {
this.onTouched = fn;
}
}
如您所见,我已经加载了一个名为 clockpicker.js
的 JavaScript 第三方。 (这只是一个简单的时钟选择器),这里是它的代码:
$(document).ready(function () {
$('.clockpicker').each(function (index, element) {
$(element).clockpicker({
afterDone: function () {
$(element).find('input[type="text"]').change();
}
});
});
});
这是我的问题:
当我直接输入此输入时,我可以通过 [(ngModel)]
获取插入的值,但是正如您所见,当 jQuery 函数填充输入值时,我无法获取填充的值值 [(ngModel)]
。
我知道这是因为它无法在 Angular 生命周期中触发 registerOnChange
事件,即使我使用
$(element).find('input[type="text"]').change();
什么都没发生。
Angular 无法了解其区域外发生的变化。这意味着您应该告诉需要 运行 更改检测周期的 Angular 应用程序,以查看是否有任何内容需要更新。
在您的情况下,您应该在组件内部初始化 clock-picker
并使用 ChangeDetectorRef
. Please read more about NgZone
检测更改,这对于执行您 Angular 区域之外的内容很有用。
有用:
我已经创建了一个自定义输入 formControl
,所以我需要通过 [(ngModel)]:
import { Component, Injector, OnInit, forwardRef } from '@angular/core';
import { ControlValueAccessor, FormControl, NG_VALUE_ACCESSOR, FormGroup } from '@angular/forms';
@Component({
selector: 'time-picker',
template:
`<input type="text" class="clockpicker" [formControl]="selectedTime" />`,
providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => TimePickerComponent),
multi: true,
}]
})
export class TimePickerComponent implements OnInit, ControlValueAccessor {
selectedTime = new FormControl('');
constructor() { }
ngAfterViewInit() {
this.scriptLoader.load(
'assets/clockpicker/clockpicker.js'
);
}
writeValue(obj: any): void {
if (this.selectedTime) {
this.selectedTime.setValue(obj);
}
}
registerOnChange(fn: any): void {
this.selectedTime.valueChanges.subscribe(fn);
}
registerOnTouched(fn: any): void {
this.onTouched = fn;
}
}
如您所见,我已经加载了一个名为 clockpicker.js
的 JavaScript 第三方。 (这只是一个简单的时钟选择器),这里是它的代码:
$(document).ready(function () {
$('.clockpicker').each(function (index, element) {
$(element).clockpicker({
afterDone: function () {
$(element).find('input[type="text"]').change();
}
});
});
});
这是我的问题:
当我直接输入此输入时,我可以通过 [(ngModel)]
获取插入的值,但是正如您所见,当 jQuery 函数填充输入值时,我无法获取填充的值值 [(ngModel)]
。
我知道这是因为它无法在 Angular 生命周期中触发 registerOnChange
事件,即使我使用
$(element).find('input[type="text"]').change();
什么都没发生。
Angular 无法了解其区域外发生的变化。这意味着您应该告诉需要 运行 更改检测周期的 Angular 应用程序,以查看是否有任何内容需要更新。
在您的情况下,您应该在组件内部初始化 clock-picker
并使用 ChangeDetectorRef
. Please read more about NgZone
检测更改,这对于执行您 Angular 区域之外的内容很有用。
有用: