1

我从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>
4

0 回答 0