我从Stack Overflow尝试了很多解决方案,但没有一个解决方案有效。
我正在使用ControlValueAccessor
并创建一个可重用的WebComponent
,以便我可以访问其他项目中的组件或元素。
为此,我在其他 Angular 项目中创建了一个JS
文件,但它显示错误imported
名称为“电子邮件”的表单控件没有值访问器
我还尝试添加ngDefaultControl
到自定义输入组件,因为我的输入消失了。
CustomEmailComponent.html
<form [formGroup]="emailForm">
<input formControlName="email" (input)="onChange($event.target.value)" (blur)="onTouch()" [placeholder]="placeholder" name="email"/>
<div *ngIf="formName.email.errors" class="invalid-feedback">
<div *ngIf="formName.email.errors.required">Email is required</div>
<div *ngIf="formName.email.errors.email">Email must be a valid email address</div>
</div>
</form>
CustomEmailComponent.ts
import { Component, forwardRef, Input, OnInit,ViewEncapsulation } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR, FormGroup, FormBuilder, Validators } from '@angular/forms';
@Component({
selector: 'custom-email',
templateUrl: './custom-email.component.html',
styleUrls: ['./custom-email.component.scss'],
providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(()=> CustomEmailComponent),
multi: true
}],
encapsulation: ViewEncapsulation.Native
})
export class CustomEmailComponent implements OnInit, ControlValueAccessor {
value= "";
email = "";
@Input() placeholder;
emailForm: FormGroup;
onChange: (val:string) => void
onTouch: () => void
writeValue(val: string): void {
this.value = val;
}
registerOnChange(fn: any): void {
this.onChange = fn;
}
registerOnTouched(fn: any): void {
this.onTouch = fn;
}
setDisabledState?(isDisabled: boolean): void {}
constructor(private fb: FormBuilder) {
this.emailForm = this.fb.group({
email: ['',[Validators.required,Validators.email]]
});
}
get formName() { return this.emailForm.controls; }
ngOnInit() {}
}
应用模块
@NgModule({
declarations: [
AppComponent,
CustomEmailComponent
],
imports: [
BrowserModule,
ReactiveFormsModule,
FormsModule
],
providers: [],
bootstrap: [AppComponent],
entryComponents: [CustomEmailComponent],
})
export class AppModule {
constructor(private injector: Injector) {}
ngDoBootstrap() {
// using createCustomElement from angular package it will convert angular component to stander web component
const el = createCustomElement(CustomEmailComponent, {
injector: this.injector
});
// using built in the browser to create your own custome element name
customElements.define('custom-email', el);
}
}
下面是其他 Angular 项目的代码
HTML 文件
<form [formGroup]="userForm">
<input formControlName="name" placeholder="Your name">
<div *ngIf="f.name.errors" class="invalid-feedback">
<div *ngIf="f.name.errors.required">Name is required</div>
</div>
<br/>
<custom-email formControlName="email" placeholder="Your email"></custom-email>
<button type="submit" [disabled]="userForm.invalid" (click)="onSubmit(userForm)">
Send
</button>
</form>
索引.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>ElementsHolder</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
<script type="text/javascript" src="assets/email-element.js"></script>
</body>
</html>