2016-12-01 70 views
3

例如,我的模板看起來像 -Angular2 - 如何訪問尚未呈現的子輸入元素?

<div #parent> 
    <button (click)="showInput()"> Show </button> 
    <input #inp *ngIf="showInpField" /> 
</div> 

這是我compoent看起來像:

import { Component, OnInit, ViewChild } from '@angular/core'; 
@Component({ 
    selector: 'some-component', 
    templateUrl: './template.html', 
}) 
export class SomeComponent { 
    @ViewChild('inp') inpField: any; 
    showInpField = false; 
    constructor() {} 
    showInput(){ 
     this.showInpField = true; 
     // This doesn't work 
     this.qaTitle.inpField.focus(); 
    } 
} 

在這種情況下,焦點不會工作,因爲輸入元素仍然沒有被渲染。我意識到在該行上使用超時會起作用,但不知何故,我覺得這不是一個好辦法。

我想我以某種方式檢測父div的變化,並在那個事件我應該做的焦點操作。我會怎麼做?我覺得QueryList可以幫助,但我無法弄清楚在這種情況下如何使用它!

回答

3

這可能是工作

@Component({ 
    selector: 'my-app', 
    template: ` 
    <div> 
     <button (click)="toggleInput()"> {{ showInpField ? 'Hide' : 'Show'}} </button> 
     <input #inp *ngIf="showInpField" /> 
    </div> 
    ` 
}) 
export class AppComponent { 
    @ViewChildren('inp', { read: ElementRef }) elemRefs: QueryList<ElementRef>; 

    showInpField = false; 

    constructor(private renderer: Renderer){} 

    toggleInput(){ 
    this.showInpField = !this.showInpField; 
    } 

    ngAfterViewInit() { 
    this.elemRefs.changes.subscribe(item => { 
     if(!this.elemRefs.length) return; 

     this.renderer.invokeElementMethod(this.elemRefs.first.nativeElement, 'focus'); 
    }) 
    } 
} 

Plunker Example

+0

我一直在尋找這樣的事情。謝謝。我現在試試看,如果有效,請勾選綠色。 – user1532043

+0

但是等一下,會不會this.viewContainerRefs.changes.subscribe工作,因爲該元素最初沒有呈現。 – user1532043

+0

真棒!謝謝。 – user1532043

3

官方的方法是使用Renderer

https://angular.io/docs/ts/latest/api/core/index/Renderer-class.html

import {Component, NgModule, Renderer, ViewChild} from '@angular/core' 
import {BrowserModule} from '@angular/platform-browser' 

@Component({ 
    selector: 'my-app', 
    template: ` 
    <div> 
     <h2 (click)="toggleInput()">Hello {{name}}</h2> 
     <input value="any other input.." /> 
     <br /> 
     <input #inpt *ngIf="showInput" /> 
    </div> 
    `, 
}) 
export class App { 
    @ViewChild('inpt') input; 
    name:string; 
    showInput = false; 

    constructor(private _renderer: Renderer) { 
    this.name = 'Angular2' 
    } 

    private toggleInput() { 
    this.showInput = !this.showInput; 

    if (this.showInput) { 
     setTimeout(() => { 
     this._renderer.invokeElementMethod(this.input.nativeElement, 'focus'); 
     }, 1); 
    } 
    } 
} 

@NgModule({ 
    imports: [ BrowserModule ], 
    declarations: [ App ], 
    bootstrap: [ App ] 
}) 
export class AppModule {} 

現場演示:https://plnkr.co/edit/DWaEvqjFARRsKg1Byeu7?p=preview

+0

非常感謝。 – user1532043