【问题标题】:I want to use ngmodel and ngforms in my angular custom element我想在我的角度自定义元素中使用 ngmodel 和 ngforms
【发布时间】:2021-09-09 02:47:06
【问题描述】:
我创建了一个带有两个输入字段的角度组件,其中包含 ngModel。现在我正在使用 angular 中的 createcustomelement api 将组件转换为自定义元素。
但转换后,我无法使用像 ngmodel 这样的角度功能。
具有此自定义元素的 JSP 页面在呈现时会出现以下错误:
“未定义的e.getDOM”
【问题讨论】:
标签:
angular
angular8
web-component
custom-element
【解决方案1】:
Angular Reactive Forms 使用名为ControlValueAccessor 的抽象模型。这是一个通用接口,允许 Angular 处理任何类型的控件值。
这是默认的:https://github.com/angular/angular/blob/master/packages/forms/src/directives/ng_model.ts
这是一个使用 Material Web 组件文本字段的实现示例:
import { Directive, forwardRef, ElementRef, HostListener } from '@angular/core';
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';
import { TextField as MWCTextField } from '@material/mwc-textfield';
export const MWC_TEXTFIELD_VALUE_ACCESSOR = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => MWCTextFieldValueAccessorDirective),
multi: true,
};
@Directive({
// eslint-disable-next-line @angular-eslint/directive-selector
selector: 'mwc-textfield[ngModel],mwc-textfield[formControl],mwc-textfield[formControlName]',
providers: [MWC_TEXTFIELD_VALUE_ACCESSOR],
})
export class MWCTextFieldValueAccessorDirective implements ControlValueAccessor {
public onChange?: (val: string) => void;
public onTouched?: () => void;
constructor(private elementRef: ElementRef<MWCTextField>) { }
@HostListener('change')
public onFieldChange(): void {
this.onChange?.(this.elementRef.nativeElement.value);
}
@HostListener('blur')
public onFieldBlur(): void {
this.onTouched?.();
}
public writeValue(value: string): void {
this.elementRef.nativeElement.value = value;
}
public registerOnChange(fn: (val: string) => void): void {
this.onChange = fn;
}
public registerOnTouched(fn: () => void): void {
this.onTouched = fn;
}
}