Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

165
Visualizações
*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', []);
    });
  }
}
about 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

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', []);
    }
  }
}
about 4 years ago · Santiago Trujillo Relatório

0

Most of the time, it doesn't work because the focus event is followed by other events. So the element lost focus. We need to use setTimeout in order to put it at the end of the Task Scheduler queue:

import { Directive, OnChanges, Input, ElementRef } from "@angular/core";

@Directive({
  selector: '[focus]'
})
export class FocusDirective implements OnChanges {
  @Input('focus') focus: boolean;

  constructor(private elementRef : ElementRef) { }

  ngOnChanges() {
    if (this.focus) {
      setTimeout(() => { this.elementRef.nativeElement.focus(); }, 0);      
    }
  }
}
about 4 years ago · Santiago Trujillo Relatório

0

A cleaner way to achieve this without having to use a directive is to use <label> instead of <button> and use css to style it like a button. For example,

<label for="myInput"></label> <input id="myInput"></input>

This way you can achieve focus even with the presence of *ngIf because the <input> is now bound to the <label>. Also, Angular2 documentation website warns about the use of ElementRef because of the security vulnerability it poses.

about 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda