typescript - div - ¿Cómo puedo establecer el foco en otra entrada?
set focus angular 4 (4)
En realidad, no necesita escribir ningún código TS para eso (estoy usando uno de los ejemplos de la otra respuesta):
<input (keyup.enter)="focusable.focus()"/>
<input #focusable />
Necesito poder cambiar el foco a un elemento de entrada cuando ocurre algún evento. ¿Cómo hago eso en Angular 2?
Por ejemplo:
<input (keyUp)="processKeyUp($event)"/>
<input (focusme)="alert(''i am focused'')"/>
Quiero enfocar el segundo cuadro de entrada cuando se presiona cierta tecla en el primero. Creo que necesito usar un evento personalizado ( focusme
en el fragmento), pero no sé dónde o cómo declararlo, y si usar una anotación @Directive
para él, o incluir su definición en un componente de alguna manera. En resumen, estoy perplejo.
ACTUALIZAR
Olvidé mencionar, sé que puedo hacerlo utilizando variables locales en el html, pero quiero poder hacerlo desde el componente, y quiero poder hacer una lógica compleja al disparar el evento focusme
para que los controles escuchen a él puede determinar si es para ellos o no. ¡Gracias!
Establecer el foco - Angular 2/5
<input type="text" [(ngModel)]="term2" #inputBox>
import { Component, ViewChild, ElementRef } from ''@angular/core'';
@Component({
selector: ''app-general'',
templateUrl: ''./general.component.html'',
styleUrls: [''./general.component.scss'']
})
export class GeneralComponent {
@ViewChild("inputBox") _el: ElementRef;
setFocus() {
this._el.nativeElement.focus();
}
}
Para establecer el enfoque en la carga
ngAfterViewInit() {
this._el.nativeElement.focus();
}
Puede actualizar esta lógica en consecuencia para presionar la tecla.
Para la manipulación en elementos DOM siempre intente utilizar directivas. En este caso, puede escribir una directiva simple.
Para acceder a DOM from directive podemos inyectar referencia de nuestro elemento host DOM por el ElementRef en el constructor de directivas.
constructor(@Inject(ElementRef) private element: ElementRef) {}
Para la detección de cambios del valor combinado , podemos usar el método ngOnChanges livecycle.
protected ngOnChanges() {}
Todo lo demás es simple.
Solución simple
// Simple ''focus'' Directive
import {Directive, Input, ElementRef} from ''angular2/core'';
@Directive({
selector: ''[focus]''
})
class FocusDirective {
@Input()
focus:boolean;
constructor(@Inject(ElementRef) private element: ElementRef) {}
protected ngOnChanges() {
this.element.nativeElement.focus();
}
}
// Usage
@Component({
selector : ''app'',
template : `
<input [focus]="inputFocused" type="text">
<button (click)="moveFocus()">Move Focus</button>
`,
directives: [FocusDirective]
})
export class App {
private inputFocused = false;
moveFocus() {
this.inputFocused = true;
// we need this because nothing will
// happens on next method call,
// ngOnChanges in directive is only called if value is changed,
// so we have to reset this value in async way,
// this is ugly but works
setTimeout(() => {this.inputFocused = false});
}
}
Solución con EventEmitter
Para resolver el problema con setTimeout (() => {this.inputFocused = false}); Podemos vincular nuestra directiva para fuente de eventos - EventEmitter u Observable. A continuación se muestra un ejemplo del uso de EventEmitter.
// Directive
import {Directive, EventEmitter, Input, ElementRef} from ''angular2/core'';
@Directive({
selector: ''[focus]''
})
class FocusDirective {
private focusEmitterSubscription;
// Now we expect EventEmitter as binded value
@Input(''focus'')
set focus(focusEmitter: EventEmitter) {
if(this.focusEmitterSubscription) {
this.focusEmitterSubscription.unsubscribe();
}
this.focusEmitterSubscription = focusEmitter.subscribe(
(()=> this.element.nativeElement.focus()).bind(this))
}
constructor(@Inject(ElementRef) private element: ElementRef) {}
}
// Usage
@Component({
selector : ''app'',
template : `
<input [focus]="inputFocused" type="text">
<button (click)="moveFocus()">Move Focus</button>
`,
directives: [FocusDirective]
})
class App {
private inputFocused = new EventEmitter();
moveFocus() {
this.inputFocused.emit(null);
}
}
Ambas soluciones resuelven su problema, pero en segundo lugar tiene un rendimiento un poco mejor y se ve mejor.
Puedes hacer esto pasando la segunda entrada como una variable a la primera
Por ejemplo
HTML
<!-- We pass focusable as a parameter to the processKeyUp function -->
<input (keyup)="processKeyUp($event, focusable)"/>
<!-- With #focusable we are creating a variable which references to the input -->
<input #focusable />
Más tarde en su js / ts
@Component({
selector: ''plunker-app''
})
@View({
templateUrl: ''main.html''
})
class PlunkerApp {
constructor() {
}
processKeyUp(e, el) {
if(e.keyCode == 65) { // press A
el.focus();
}
}
}
el es el elemento raw, por lo que puedes usar javascript puro en él.
Aquí hay un plnkr para que pueda verlo funcionando.
Espero que ayude.