2016-03-31 9 views
9

Ich kann so etwas in der Dokumentation oder Google Beispiele finden.Angular 2 - Wählen Sie ein Objekt aus dem DOM und setzen Sie den Fokus

Ich habe viele Eingabefelder in ein Div und ich muss eine bestimmte programmgesteuert auswählen. Wie es geht ?

So etwas wie

<div> 
<input type="text" name="txt1" /> 
<input type="text" name="txt2" /> 
<input type="text" name="txt3" /> 
<input type="text" name="txt4" /> 
<input type="text" name="txt5" /> 
<input type="text" name="txt6" /> 
</div> 
<button (click)="selectSample()" /> 

selectSample() { 
    ?????????('txt3').focus(); 
    console.log('Button pressed, txt3 has been selected'); 
} 
+0

versuchen, Referenz mit Java-Skript wie 'document.getElementByid ('')' nehmen oder etwas Code zu posten, um es klarer zu machen –

+0

Es ist Angular 2, Pardeep –

+1

Sieht aus wie http://stackoverflow.com/questions/34522306/ angular-2-focus-on-neu-hinzugefügt-input-element/34573219 # 34573219 –

Antwort

10
@Component({ 
    selector: 'my-app', 
    template: ` 
<div> 
<input #input type="text" name="txt1" /> 
<input #input type="text" name="txt2" /> 
<input #input type="text" name="txt3" /> 
<input #input type="text" name="txt4" /> 
<input #input type="text" name="txt5" /> 
<input #input type="text" name="txt6" /> 
</div> 
<button (click)="selectSample()">click</button> 
` 
}) 
export class App { 
    @ViewChildren('input') inputs; 

    selectSample() { 
    // console.debug(this.inputs.toArray().find((e) => { 
    // return e.nativeElement.getAttribute('name') == 'txt3'; 
    //}).nativeElement.value); 

    this.inputs.toArray().find((e) => { 
     return e.nativeElement.getAttribute('name') == 'txt3'; 
    }).nativeElement.focus(); 

    } 
} 

Plunker example

+1

ViewChildren (Eingang) Eingänge; <- Eingabe nicht definiert –

+0

Danke, ich habe es beim Bau des Plunkers entdeckt. Wenn Sie im Voraus (Build-Zeit) wissen, dass Sie wollen, 'dann ist @PierreDuc Ansatz der bessere. Wenn Sie dynamisch einen basierend auf dem Namen auswählen möchten, funktioniert mein Ansatz möglicherweise besser. –

+0

Ja ... Es muss dynamisch sein, also ist Ihr Ansatz besser geeignet. Ich habe gerade txt3 als Beispiel verwendet. –

8

Werfen Sie einen Blick auf die ViewChild (und ViewChildren wie Gunter schlägt) Anmerkungen.

Sie können etwas tun:

@Component({ 
    selector: 'samples', 
    template: ` 
    <div> 
     <input type="text" name="txt1"> 
     <input type="text" name="txt2"> 
     <input type="text" name="txt3" #input3> 
     <input type="text" name="txt4"> 
     <input type="text" name="txt5"> 
     <input type="text" name="txt6"> 
    </div> 
    <button (click)="selectSample()">select</button>` 
})  
export class SamplesComponent { 

    @ViewChild('input3') input3:ElementRef; 

    constructor(private _renderer : Renderer) {} 

    public selectSample() { 
    //as per Eric's suggestion 
    this._renderer.invokeElementMethod(this.input3.nativeElement, 'focus', []); 
    } 
} 
+3

Diese Lösung ist viel sauberer, upvoted. Obwohl ich stattdessen Renderer und eine Direktive verwendet hätte. –

+0

@EricMartinez Ohh, würdest du dir das ansehen? Ich nehme an, Sie sprechen von 'Renderer' in Kombination mit' invokeElementMethod'? Ich habe mir nur die Dokumentation angeschaut, noch nie von Renderer gehört. Danke für diese Idee. Ich mag die Idee auch nicht, 'nativeElement' zu verwenden. – PierreDuc

+0

Ja, der direkte Zugriff auf nativeElement wird nicht empfohlen, siehe [ElementRef] (https://angular.io/docs/ts/latest/api/core/ElementRef-class.html), so ist der sicherste Weg, Renderer zu verwenden, da Webworker sicher ist. –

4

Hier ist eine Richtlinie Implementierung pro Erics Vorschlag:

@Directive({selector: 'input'}) 
export class MyInput { 
    constructor(private _elRef:ElementRef, private _renderer:Renderer) {} 
    focusIf(attrValue:string) { 
    console.log(this._elRef.nativeElement.getAttribute('name')) 
    if(this._elRef.nativeElement.getAttribute('name') === attrValue) { 
     this._renderer.invokeElementMethod(this._elRef.nativeElement, 'focus', []); 
     return true; 
    } 
    return false; 
    } 
} 

@Component({ 
    selector: 'my-app', 
    directives: [MyInput], 
    template: `<div> 
     <input type="text" name="txt1"> 
     <input type="text" name="txt2"> 
     <input type="text" name="txt3"> 
     <input type="text" name="txt4"> 
     <input type="text" name="txt5"> 
     <input type="text" name="txt6"> 
    </div> 
    <button (click)="selectSample()">click</button>` 
}) 
export class AppComponent { 
    @ViewChildren(MyInput) inputs; 
    constructor() { console.clear(); } 
    selectSample() { 
    this.inputs.toArray().some(myInput => 
     myInput.focusIf('txt3')); 
    } 
} 

Plunker

I der Richtlinie Ansatz mögen, weil wir don Sie müssen #input nicht zum HTML hinzufügen, und die Direktive weiß, wie sie sich selbst konzentriert.

Ich verwendete Array.some(), nur um etwas effizienter zu sein.

+0

Renderer ist veraltet und neu [Renderer2 hat keine invokeElementMethod] (https://github.com/angular/angular/issues/13818#issuecomment-283417820) -Methode. – Makla

3

Mein Ansatz wäre, sich auf eine Direktive und ihren Selektor zu verlassen, die Notwendigkeit der Iteration über ein Array zu beseitigen und die lokalen Variablen zu vermeiden (Ich mag die Idee nicht, zu viele davon aus meiner Sicht zu haben)), wie Mark erwähnte.

Ich gehe davon aus, dass der Benutzer immer nur eine wollen und es ist hardcoded, das ist genug für den Fall der Benutzer gefragt. Ein dynamisches Element zu fokussieren würde diesen Ansatz zunichte machen.

Die Richtlinie

@Directive({ 
    selector : 'input[type=text][name=txt3]' 
}) 
class Input { 
    constructor(public renderer: Renderer, public elementRef: ElementRef) {} 

    focusMe() { 
    this.renderer.invokeElementMethod(this.elementRef.nativeElement, 'focus', []); 
    } 
} 

Die Komponente würde in jeder grundsätzlich die gleichen sein beantworten

export class App { 
    @ViewChild(Input) input: Input; 

    selectSample() { 
    this.input.focusMe(); 
    } 
} 

Hier ist die plnkr.

+0

Renderer ist veraltet und neu [Renderer2 verfügt nicht über invokeElementMethod] (https://github.com/angular/angular/issues/13818#issuecomment-283417820) -Methode. – Makla

Verwandte Themen