In Angular2, come posso impostare il binding sull'elemento focus. Non voglio impostarlo con elementRef. Penso che in AngularJS c'è direttiva ngFocus In Angular2 non esiste una direttivaCome impostare lo stato attivo sull'elemento con associazione?
risposta
Un semplice 'focus' direttiva
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});
}
}
Il miglior modo di messa a fuoco su un elemento con angular2 è quello di utilizzare il Renderer
e invocare un metodo sull'elemento. Non c'è modo di farlo senza elementRef
.
Questo si traduce in qualcosa di simile:
this.renderer.invokeElementMethod(this.input.nativeElement, 'focus', []);
Dove renderer
ottiene iniettato nel costruttore utilizzando protected renderer : Renderer
Molto più modo più semplice:
import { Directive, ElementRef, Renderer} from "@angular/core";
@Directive({
selector: "[Focus]"
})
export class myFocus {
constructor(private _el: ElementRef, private renderer: Renderer) {
this.renderer.invokeElementMethod(this._el.nativeElement, 'focus');
}
}
Ho provato entrambe le varianti, ma nessuna è adatta per un uso semplice. 1st (by @AngJobs) ha bisogno di ulteriore lavoro nel componente in cui usi direttiva (per impostare focus = true), 2nd (by @ShellZero) non funziona affatto perché il focus chiama prima che la vista sia effettivamente pronta. Così ho spostato la chiamata di messa a fuoco su ngAfterViewInit
. Ora puoi solo aggiungere <input focus...
e dimenticarlo. L'elemento otterrà la messa a fuoco dopo l'avvio della visualizzazione automaticamente.
import { Directive, ElementRef, Renderer, AfterViewInit } from '@angular/core';
@Directive({
selector: '[focus]'
})
export class DmFocusDirective implements AfterViewInit {
constructor(private _el: ElementRef, private renderer: Renderer) {
}
ngAfterViewInit() {
this.renderer.invokeElementMethod(this._el.nativeElement, 'focus');
}
}
Grazie - questo è fantastico. Anche se il nome della tua classe non ha necessariamente bisogno di prefisso (come hai fatto con 'Dm'). Il bit chiave per applicare un prefisso è il valore del nome del selettore. cioè selettore: '[appFocus]' '. Immagino che questo riduca la probabilità di collisioni nelle successive versioni angolari, ecc. – ne1410s
Avviso: 'Renderer' è deprecato, e il team Angular non prevede di portare' invokeElementMethod() 'forward in' Renderer2'. https://github.com/angular/angular/issues/13818 – stealththeninja
Funziona per me ma ha errori nella console. Dopo il debug e la ricerca trovato questo articolo: https://www.picnet.com.au/blogs/guido/post/2016/09/20/angular2-ng2-focus-directive/
Basta copia-incolla. Ha funzionato perfettamente per me.
import {Directive, AfterViewInit, ElementRef, DoCheck} from '@angular/core';
@Directive({selector: '[focus]'})
export class FocusDirective implements AfterViewInit, DoCheck {
private lastVisible: boolean = false;
private initialised: boolean = false;
constructor(private el: ElementRef) {
}
ngAfterViewInit() {
console.log('inside FocusDirective.ngAfterViewInit()');
this.initialised = true;
this.ngDoCheck();
}
ngDoCheck() {
console.log('inside FocusDirective.ngDoCheck()');
if (!this.initialised) {
return;
}
const visible = !!this.el.nativeElement.offsetParent;
if (visible && !this.lastVisible) {
setTimeout(() => {
this.el.nativeElement.focus();
}, 1);
}
this.lastVisible = visible;
}
}
servizio renderer è ora deprecated (come di 4.x angolare) Il nuovo servizio Renderer2 non ha l'invokeElementMethod. Cosa si può fare è quello di ottenere un riferimento all'elemento in questo modo:
const element = this.renderer.selectRootElement('#elementId');
E poi si può usare quello per concentrarsi su questo elemento in questo modo:
element.focus();
Di più su come selectRootElement
funziona here :
EDIT:
Se l'elemento non viene messo a fuoco il problema comune è che l'elemento non è pronto. (es .: disabilitato, nascosto ecc.). Si può fare questo:
setTimeout(() => element.focus(), 0);
Questo creerà un macrotask che verrà eseguito nel prossimo VM turno, quindi se è stata attivata l'elemento il fuoco verrà eseguita correttamente.
import { Directive, ElementRef, AfterViewChecked } from '@angular/core';
@Directive({
selector: '[autoFocus]',
})
export class FocusDirective implements AfterViewChecked {
constructor(private _elementRef: ElementRef) { }
ngAfterViewChecked() {
this._elementRef.nativeElement.focus()
}
}
- 1. Impostare lo stato attivo su un pulsante
- 2. WPF: Impossibile impostare lo stato attivo
- 3. Impostare lo stato attivo sull'elemento contented div
- 4. Summernote: impostare lo stato attivo dopo l'inizializzazione
- 5. Come impostare lo stato attivo del widget Tkinter?
- 6. Come impostare lo stato attivo su un'altra finestra?
- 7. Come impostare lo stato attivo su una finestra modale javascript?
- 8. Come impostare lo stato attivo su UserControl (renderlo selezionabile)?
- 9. Come impostare lo stato attivo su un materiale TextField?
- 10. Come impostare lo stato attivo su un elemento in Elm?
- 11. Impostare lo stato attivo su UITextField in tableCell
- 12. Impostare lo stato attivo sul campo in DIV dinamicamente caricato
- 13. Impostare lo stato attivo sull'ingresso successivo in jQuery?
- 14. Imposta lo stato attivo su un componente con Apache Wicket?
- 15. Come avviare jquery datepicker con lo stato attivo
- 16. Come si imposta lo stato attivo su Textfield in Swing?
- 17. Bootstrap 3 Scrollspy rimuove lo stato attivo
- 18. Come impostare lo stato di hover equivale allo stato attivo con li clearfix utilizzando ui-sref-active = "active"
- 19. editText non perde lo stato attivo
- 20. Android ListView personalizzato con ImageButton non ottiene lo stato attivo
- 21. Come impostare lo stato attivo su una particolare riga in un datagrid/gridview?
- 22. Forza lo stato attivo su un elemento con un'eccezione. (jQuery)
- 23. Come impostare lo stato attivo sul primo campo di input in BootStrap?
- 24. Come impostare lo stato attivo su un controllo in un'applicazione Windows Form?
- 25. Come impostare lo stato dirty di Ext.Form?
- 26. Come impostare lo stato attivo su qualsiasi oggetto in MS Access utilizzando VBA
- 27. Come ottenere una combobox per impostare correttamente lo stato attivo direttamente dopo la chiusura del popup
- 28. Come faccio a impostare lo stato attivo a una casella di testo Html.TextBoxFor - MVC 2
- 29. Come impostare lo stato attivo quando ci sono molte caselle di testo che usano jquery?
- 30. Come impostare lo stato attivo su un controllo all'interno di un controllo personalizzato?
Un piccolo heads-up. Non utilizzare direttamente 'nativeElement'. Questo non è risparmiato con i webworker. – PierreDuc
La proprietà 'direttivo' è stata rimossa in RC 6. È necessario spostare' FocusDirective' nella proprietà dichiarazioni del decoratore NgModule. – cnotethegr8
Ho lo stesso requisito ma, voglio spostare il setTimeout all'interno della direttiva, si può ottenere la stessa funzionalità usando setTimeout all'interno della direttiva? –