Search code examples
angularinputfocusangular-ng-if

*ngIf with focus directive


In my app, I tried to place a button that shows/hides an input field with a boolean component property. If the button shows the input, focus should be set on the input. But it seems not to work. If I remove the *ngIf the focus directive works fine.

I created a plunker that shows what I mean. It's kind of difficult to describe my problem.

HTML in a component:

<input *ngIf="filterShow.options"
       [focus]="filterFocus.options"
       [(ngModel)]="filter.options">

<button type="button"
        (click)="setShowFilter('options')">
  focus
</button>

setShowFilter() method:

private setShowFilter(filter: string) {
  this.filterShow[filter] = !this.filterShow[filter];

  /* reset filter */
  this.filter[filter] = "";

  this.filterFocus[filter].emit(true);
}

focus.directive.ts:

@Directive({
  selector: '[focus]'
})
export class FocusDirective implements OnInit {

  @Input('focus') focusEvent: EventEmitter<boolean>;

  constructor(private elementRef : ElementRef,
              private renderer   : Renderer   ) { }

  ngOnInit() {
    this.focusEvent.subscribe(event => {
      this.renderer
        .invokeElementMethod(this.elementRef.nativeElement, 'focus', []);
    });
  }
}

Solution

  • EventEmitters are for @Outputs, not for @Inputs. Try something like this instead:

    @Directive({
      selector: '[focus]'
    })
    export class FocusDirective implements OnChanges {
    
      @Input('focus') focus: boolean;
    
      constructor(private elementRef : ElementRef,
                  private renderer   : Renderer   ) { }
    
      ngOnChanges() {
        if (this.focus) {
          this.renderer
            .invokeElementMethod(this.elementRef.nativeElement, 'focus', []);
        }
      }
    }