简体   繁体   中英

Angular - How do I detect form events from inside a directive when they are initiated in component.ts file?

If I have a component with a form input and I want to detect the two statements in the OnInit block as events inside my directive, what is the correct way to do this? I have had luck with 'input' and 'ngModelChange', but none of the events I try to listen to catch the patchValue() method for model driven forms or the straight assignment for template driven forms (even though it reflects in the DOM).

Here is my Component:

import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms' 

@Component({
  selector: 'my-app',
  template:
  `
  <h5>Model form input</h5>
  <form [formGroup]="inputForm">
    <input patchable-input formControlName="input" />
  </form>

  <h5>Template form input</h5>
  <input patchable-input [(ngModel)]="input" />
  `
})
export class AppComponent implements OnInit {
  inputForm = new FormGroup({
    input: new FormControl('')
  })

  input = '';

  ngOnInit() {
    this.inputForm.patchValue({
      input: 'testing patch'
    })

    this.input = 'testing override'
  }
}

Here is my Directive:

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

@Directive({
  selector: '[patchable-input]'
})
export class PatchableInputDirective  {
  @HostListener('ngModelChange', ['$event']) ngOnChanges($event) {
        console.log($event);
    }
}

and a minimal reproduction in StackBlitz (watch the console)

You have to implement AfterViewInit instead of OnInit . The reason for that is at this point in the life cycle your directive has been initialized and has subscribed to the ngModelChange event via the @HostListener decorator.

See also the Angular Life Cycle Hooks documentation .

stackblitz


import { Component, AfterViewInit } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms' 

@Component({
  selector: 'my-app',
  template:
  `
  <h5>Model form input</h5>
  <form [formGroup]="inputForm">
    <input patchable-input formControlName="input" />
  </form>

  <h5>Template form input</h5>
  <input patchable-input [(ngModel)]="input" />
  `
})
export class AppComponent implements AfterViewInit {
  inputForm = new FormGroup({
    input: new FormControl('')
  })

  input = '';

  ngAfterViewInit() {
    this.inputForm.patchValue({
      input: 'testing patch'
    })
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM