如何在 Angular 中处理自定义输入组件上的输入事件?

Posted

技术标签:

【中文标题】如何在 Angular 中处理自定义输入组件上的输入事件?【英文标题】:How to handle input events on custom input component in Angular? 【发布时间】:2020-01-17 05:44:25 【问题描述】:

我正在尝试使用 Angular 7 中的 Reative Form 创建自定义输入组件,但我无法将事件传递到输入字段。

我的component 有一个标签、一个输入字段和一个特定的布局。我的component html 看起来像这个

<div id="customInputGroup"  [formGroup]="parentFormGroup" [ngClass]="'input-value': hasValue()">
    <label [for]="inputId">label</label>
    <input [id]="inputId"  [name]="inputName"  class="form-control" [placeholder]="placeholder" [formControlName]="inputName" [mask]="mask">
</div>

我的Component

@Component(
  selector: 'app-input-field',
  templateUrl: './input-field.component.html',
  styleUrls: ['./input-field.component.css']
)
export class InputFieldComponent implements OnInit 


  @Input('placeholder') placeholder = '' ;
  @Input('label') label = '';
  @Input('inputId') inputId = '';
  @Input('inputName') inputName = '';
  @Input('parentFormGroup') parentFormGroup:FormGroup;
  @Input('mask') mask;
  constructor()  

  ngOnInit() 
  

  hasValue()
    return (this.parentFormGroup.get(this.inputName).value != undefined 
    && this.parentFormGroup.get(this.inputName).value != null 
    && this.parentFormGroup.get(this.inputName).value != '')
  

在我不得不处理输入onBlur 事件(或者它可以是任何其他输入事件)之前,一切正常。 我想要的结果是调用我的component 传递像 this 这样的任何事件:

<app-input-field (blur)="functionName()"></app-input-field>

<app-input-field (keyup)="functionName()"></app-input-field>

我的component 将能够“动态地”将这些事件传递给我的输入字段。有可能吗?

【问题讨论】:

InputFieldComponent 应该实现 ControlValueAccessor 【参考方案1】:

blur 这样的事件适用于 input field ,而不是像 &lt;app-input-field&gt; 这样的选择器

您可以为所有事件发出事件,例如模糊、按键、鼠标悬停等。

InputFieldComponent

HTML:

<input (blur)="functionName('blur')" (keyup)="functionName('keyUp')" [id]="inputId"  [name]="inputName"  class="form-control" [placeholder]="placeholder" [formControlName]="inputName" [mask]="mask">

TS:

@Output() OnInputEvent= new EventEmitter();

functionName(eventName) 
    this.OnInputEvent.emit(eventName);

在您的组件中:

<app-input-field (OnInputEvent)="functionName($event)"></app-input-field>

TS:

functionName(event) 
    switch (event) 
       case "blur":
       ...
       break;

       case "keyUp":
       ...
       break;
    

Working Demo

【讨论】:

? 你做得很好@Adrita,对于 keyup 事件,你不需要做任何事情它会冒泡,你可以在元素本身上捕捉它但不要模糊,检查我的答案☕跨度> 感谢@malbarmawi,您的解决方案也很棒。但我只是认为通过从输出中发出所有事件,它们可以在同一个地方处理 ? 我们俩的答案都是正确的,可以将两者结合在一起?,我喜欢将所有事件组合到一个事件中的想法,up ? 但如果组件用作输入元素的包装器并将以反应形式使用,他必须实现 ControlValueAccessor ,我认为? 是的,我读过ControlValueAccessor,但从未真正使用过它,也许您可​​以使用它添加答案,我会去了解它【参考方案2】:

对于模糊事件,您需要创建一个具有相同名称的事件发射器并在输入元素模糊发射时发出此事件

export class InputFieldComponent implements OnInit 

  @Output() blur:EventEmitter<any> = new EventEmitter(); // ?

  constructor()  

  ngOnInit() 
  


模板

<input type="text" (blur)="blur.emit($event)"  >

app.template

<app-input-field (blur)="onBlur($event)" (keyup)="onKeyup($event)"></app-input-field>

我们为 blur 事件执行此操作,因为该事件不是气泡,keyup 将在不创建任何自定义事件的情况下工作,因为它会冒泡。

demo ??

你可以像这样实现两种方式的数据绑定

  @Input() value:EventEmitter<any> = new EventEmitter();

  @Output() valueChange:EventEmitter<any> = new EventEmitter();

模板

<app-input-field  [(value)]="name" ></app-input-field>

demo ??

任何气泡事件,例如输入、按键、keyup、keydown,您都可以在元素本身上捕获,或者您可以像我们在 blur 事件中所做的那样解决它。

【讨论】:

以上是关于如何在 Angular 中处理自定义输入组件上的输入事件?的主要内容,如果未能解决你的问题,请参考以下文章

Angular:在 NgForm 的自定义输入组件中调用 markAsDirty()

如何在 Angular 中为自定义组件实现伪事件?

如何使用 ControlValueAccessor Angular 在自定义输入中使用指令

Angular自定义组件实现数据双向数据绑定

Angular:使用 ControlValueAccessor 自定义输入

自定义 angular2 表单输入组件,在组件内具有两种方式绑定和验证