【问题标题】:No provider for NgControl inside CustomDirective despite imported forms modules Angular2+尽管导入了表单模块 Angular2+,但 CustomDirective 中没有 NgControl 提供者
【发布时间】:2020-07-15 14:20:24
【问题描述】:

所以,我正在创建一个自定义指令,并且需要在其中使用表单控件。但我遇到了一个错误: NgControl 没有提供者;我知道正确的答案是:导入响应式表单模块,但我已经导入了!

import { Directive, ElementRef, Input, HostListener, OnDestroy } from '@angular/core';
import { NgControl } from '@angular/forms'
@Directive({
  selector: '[testDirective]'
})
export class TestDirectiveClass implements OnDestroy{

  constructor(private elementRef: ElementRef, c: NgControl ) { }

    ngOnDestroy() {

  }

}

我的组件:

<p testDirective>
  Start editing to see some magic happen :)
</p>

还有我的 appModule:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { TestDirectiveClass } from './testDirective.directive';
import { AppComponent } from './app.component';
import { HelloComponent } from './hello.component';

@NgModule({
  imports:      [ BrowserModule, FormsModule, ReactiveFormsModule ],
  declarations: [ AppComponent, HelloComponent, TestDirectiveClass ],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }

my stackblitz

【问题讨论】:

    标签: angular forms dependency-injection import angular-directive


    【解决方案1】:

    抛出异常,因为p 元素缺少[formControlName] 指令。接下来是使用 HTML 表单元素,例如 input, select, radio button, etc. 这是因为 Angular 为默认表单元素定义了 ControlValueAccessor,而 p 仅用于表示文本,它没有像 @987654326 这样的能力@。

    app.component.html

    <div [formGroup]="form">
      <input testDirective formControlName="testControl">
        Start editing to see some magic happen :)
    </div>
    

    app.component.ts

    import { Component, VERSION, OnInit } from '@angular/core';
    import { FormGroup, FormBuilder, FormControl } from '@angular/forms';
    
    @Component({
      selector: 'my-app',
      templateUrl: './app.component.html',
      styleUrls: [ './app.component.css' ]
    })
    export class AppComponent  implements OnInit{
      name = 'Angular ' + VERSION.major;
    
      form: FormGroup;
    
      constructor(private fb: FormBuilder) {}
    
      ngOnInit() {
        this.form = this.fb.group({
          testControl: [null]
        })
      }
    }
    

    Angular 文档还说:

    所有基于 FormControl 的控制指令扩展的基类。它将 FormControl 对象绑定到 DOM 元素。

    【讨论】:

      【解决方案2】:

      您可以添加装饰器 @Optional

      用于构造函数参数的参数装饰器,将参数标记为可选依赖项。如果未找到依赖项,DI 框架将提供 null。

      import { Directive, Optional, ElementRef, Input, HostListener, OnDestroy } from '@angular/core';
      import { NgControl } from '@angular/forms'
      @Directive({
        selector: '[testDirective]'
      })
      export class TestDirectiveClass implements OnDestroy{
      
        constructor(
          @Optional() public c: NgControl,
         private elementRef: ElementRef  ) { }
        
        ngOnDestroy() {
          
        }
      
      }
      

      https://stackblitz.com/edit/angular-ivy-sjr7q7

      【讨论】:

      • 感谢您的回答!它改变了什么?我的意思是,对我来说这是一种奇怪的行为,因为我已经看到没有任何装饰器的解决方案,只需将导入和初始化到构造函数中。但是现在好像不行了。
      • 它不起作用?避免编译时找不到任何模块(尤其是使用AOT)
      猜你喜欢
      • 2019-04-23
      • 2017-07-21
      • 2019-08-12
      • 1970-01-01
      • 1970-01-01
      • 2016-07-27
      • 2011-02-07
      • 2018-05-04
      • 2021-03-20
      相关资源
      最近更新 更多