首页 > 解决方案 > 我想在我的角度自定义元素中使用 ngmodel 和 ngforms

问题描述

我创建了一个带有两个输入字段的角度组件,其中包含 ngModel。现在我正在使用 angular 中的 createcustomelement api 将组件转换为自定义元素。

但转换后,我无法使用像 ngmodel 这样的角度特性。

具有此自定义元素的 JSP 页面在呈现时会出现以下错误:

“未定义的 e.getDOM”

标签: angularangular8web-componentcustom-element

解决方案


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;
    }
}


推荐阅读