模板解析错误:创建自定义表单元素时没有 NgControl 的提供程序

Template parse errors: No provider for NgControl when creating custom form elements

我一直在尝试使用 angular 元素创建自定义元素,对于表单输入,我一直在尝试使用 angular 的 ControlValueAccessor,如 this 中所述Eli运行 Eliassy 的文章。

但是当我按照指南完成代码时 - 我 运行 遇到了这个问题。 没有 NgControl 的供应商。我已经将 FormsModule 和 ReactiveFormsModule 导入到 app.module.ts 文件中,这是此错误的补救措施(正常情况下)。但是这次还没有修好。

StackBlitz Example

会有什么问题?我附上上面的stackbliz供您参考。

您的 AppModule 和 DoBootstrap 实现有问题。如果您删除它并另外从 appModule 中的 entryComponents 中删除您的组件并更改它在应用程序中的使用方式-component.html 一切似乎都工作正常。

app.module.ts

@NgModule({
  imports: [BrowserModule, FormsModule, ReactiveFormsModule],
  declarations: [AppComponent, HelloComponent, TestInputComponent],
  bootstrap: [AppComponent],
  schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class AppModule  {
  constructor(private injector: Injector) {

  }
}

app.component.html

<form class="form-signin" (ngSubmit)="onSubmit(f.value)" #f="ngForm" >
  <app-test-input [placeholder]="'Email'"
                          [isRequired]="true"
                          [errorMsg]="'Please enter your name'"
                          [label] = "'User Email'"
                          [pattern]="'[A-Za-z0-9._%-]+@[A-Za-z0-9._%-]+\.[a-z]{2,3}'"
                          ngModel name="email"></app-test-input>

  <button class="btn btn-lg btn-primary btn-block" [disabled]="!f.valid" type="submit">Sign in</button>
</form>

从您的 app.module.ts

中删除此行
entryComponents: [TestInputComponent]

您还从 app.module.ts 中删除了 DoBootstrap 实现 并将 ust-input 替换为 app-test-input,它将 works.also 删除

providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: TestInputComponent,
      multi: true
    }]

因为它会产生循环依赖。

感谢您在这里发帖,让更多人受益。

你在那里犯了 2 个错误:

  1. 当您注入 NgControl 时,您不必提供 NG_VALUE_ACCESSOR 令牌。原因是 NgControl 已经提供了 NG_VALUE_ACCESSOR 令牌,如果你也这样做,你将 运行 陷入循环依赖问题。

  2. 因为你的TestComponent是一个入口组件,你还必须在你的NgControl注入之前添加@Optional()装饰器。原因是当你在入口组件中声明一个组件时,angular 编译它工厂即使它不在模板上,并且因为它不是任何形式的一部分并且没有任何 From 指令,你会得到 No provider for NgControl

  3. 这个错误

希望对您有所帮助!

找到解决方案。

通过在自定义元素中添加 ngDefaultControl 作为指令并手动实现 ControlValueAccessor 的一部分来修复错误。

这里是一个实现的例子(验证部分不要介意,还没完) StackBlitz

请关注这些问题以获取更多信息。