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

问题描述 投票:0回答:6

我一直在尝试使用 Angular 元素创建自定义元素,对于表单输入,我一直在尝试使用 Angular 的 ControlValueAccessor 来实现这一点,如 Eliran Eliassy 的 this 文章中所讨论的。

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

StackBlitz 示例

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

angular angular-forms angular-elements
6个回答
3
投票

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

你犯了两个错误:

  1. 当您注入

    NgControl
    时,您不必提供
    NG_VALUE_ACCESSOR
    令牌。原因是
    NgControl
    已经提供了
    NG_VALUE_ACCESSOR
    令牌,如果您也这样做,您将遇到循环依赖问题。

  2. 因为您的

    TestComponent
    是入口组件,所以您还必须在
    @Optional()
    注入之前添加
    NgControl
    装饰器。原因是当你在入口组件中声明一个组件时,Angular 会在工厂编译它,即使它不在模板上,并且因为它不属于任何表单,并且上面没有任何 From 指令,所以你会得到以下错误
    No provider for NgControl

希望有帮助!


1
投票

您的 AppModule 和 DoBootstrap 实现有问题。如果您删除它并另外从 appModule 中的 entryComponents 中删除您的组件并更改它在 app-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>

1
投票

找到解决方案。

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

这是一个实现示例(不要介意验证部分,尚未完成) 堆栈闪电战

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


0
投票

从你的 app.module.ts 中删除这一行

entryComponents: [TestInputComponent]

您还从 app.module.ts 中删除了 DoBootstrap 实现 并将 ust-input 替换为 app-test-input ,它将起作用。同时删除

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

因为它会产生循环依赖。


0
投票

对于其他收到此错误的人来说,就我而言,问题是缺少 formControlName 属性和缺少 formGroup 作为父级。如果您也在项目中使用自定义表单控件,请确保所有引用 - formControlName 和 [formGroup]="myFormGroup" - 均已正确设置。


0
投票

在您的

NgControl
中提供
TestingModule
,如下所示:

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [ ... ReactiveFormsModule, FormsModule ... ],
      declarations: [
        ...Component,
      ],
      providers: [NgControl], // <-- this
    });
    fixture = TestBed.createComponent(...Component);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });
© www.soinside.com 2019 - 2024. All rights reserved.