我确实想创建一个不包含任何输入的自定义控件。每当控件更改时,我都想保存完整的表单。
我们当前的方法使用这样的表单更改事件:
<form #demoForm="ngForm" (change)="onChange()">
<custom-input name="someValue" [(ngModel)]="dataModel">
</custom-input>
</form>
如您所见,我们使用“更改”事件来响应表单中的任何更改。只要我们有输入、复选框……作为控件,这就可以正常工作。
但是我们的自定义控件只存在于我们可以单击的简单 div 之外。每当我单击 div 时,控件的值都会增加 1。但是不会触发表单的“更改”事件。我是否必须以某种方式将我的自定义控件链接到表单?或者是否有任何事件需要触发?
import { Component, forwardRef } from '@angular/core';
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';
@Component({
selector: 'custom-input',
template: `<div (click)="update()">Click</div>`,
providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CustomInputComponent),
multi: true
}]
})
export class CustomInputComponent implements ControlValueAccessor {
private onTouchedCallback: () => void = () => {};
private onChangeCallback: (_: any) => void = () => {};
update(){
this.value++;
}
get value(): any {
return this.innerValue;
};
set value(v: any) {
console.log("Change to");
if (v !== this.innerValue) {
this.innerValue = v;
this.onChangeCallback(v);
}
}
writeValue(value: any) {
if (value !== this.innerValue) {
this.innerValue = value;
}
}
registerOnChange(fn: any) {
this.onChangeCallback = fn;
}
registerOnTouched(fn: any) {
this.onTouchedCallback = fn;
}
}
我创建了一个 plunker 来演示这个问题: https://plnkr.co/edit/ushMfJfcmIlfP2U1EW6A
每当您单击“单击”时,模型值都会增加,但控制台上没有输出,因为未触发更改事件…(有一个 console.log 链接到更改事件)
原文由 Stefan 发布,翻译遵循 CC BY-SA 4.0 许可协议
感谢您的回复。
最后我找到了这个问题的以下解决方案:正如 Claies 在评论中提到的,我的自定义组件不会触发 change 事件。因此,表格永远不会知道更改。这与角度无关,但如前所述,这是输入/表单的预期行为。
最简单的解决方案是在发生更改时触发自定义控件中的更改事件:
就是这样,每当我在自定义组件中调用“onControlChange(..)”时,我都会在之后触发此事件。
请注意,您需要 Custom-Event-Polyfill 来支持 IE! https://www.npmjs.com/package/custom-event-polyfill