首页 > 解决方案 > 如何使用 ControlValueAccessor Angular 在自定义输入中使用指令

问题描述

我已经input在我的 Angular 应用程序使用中创建了一个简单的自定义组件ControlValueAccessor。所以,当我想创建一个表单input元素时,我不必调用<input />,只需调用<my-input>

我有一个问题,当我使用时<input />,我可以使用myDirective. 例如:

<input type="text" class="form-control" formControlName="name" myDirective />

但是,当我使用 时my-input,我无法使用myDirective. 例如:

<my-input formControlName="name" myDirective></my-input>

myDirective在我的输入中不起作用

这是my-input组件使用ControlValueAccessor代码:

import { Component, forwardRef } from '@angular/core';
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';

@Component({
  selector: 'my-input',
  templateUrl: './my-input.component.html',
  styleUrls: ['./my-input.component.scss'],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(()  => MyInputComponent ),
      multi: true
    }
  ]
})

export class MyInputComponent implements ControlValueAccessor {

  onChange: () => void;
  onTouched: () => void;

  value: string;

  writeValue(value: string): void {
    this.value = value ? value : '';
  }

  registerOnChange(fn: any): void {
    this.onChange = fn;
  }

  registerOnTouched(fn: any): void {
    this.onTouched = fn;
  }
}

更新: myDirective代码:

import { Directive, HostListener } from '@angular/core';
import { FormControlName } from '@angular/forms';

@Directive({
    selector: '[myDirective]'
})

export class MyDirective{
    constructor(private formControlName: FormControlName) { }

    @HostListener('input', ['$event']) 
    onInputChange() {
        this.formControlName.control.setValue(this.formControlName.value.replace(/[^0-9]/g, ''));
    }
}

有没有办法myDirectivemy-input组件中使用?

提前致谢。

标签: angularangular-directivecontrolvalueaccessor

解决方案


你的指令有问题。注入一个NgControl并控制这个 ngControl

export class MyDirective{
    constructor(private control: NgControl) { } //<--inject NgControl

    @HostListener('input', ['$event']) 
    onInputChange() {
        this.control.control.setValue(this.control.value.replace(/[^0-9]/g, ''));
    }
}

你可以在stackblitz中看到

注意:不要忘记包含在模块声明中

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

推荐阅读