如何获得angular2的DOM元素

我有一个有p元素的组件。 它的onClick事件会将其更改为textarea以便用户可以编辑数据。 我的问题是:

  • 我怎么能把重点放在textarea上?
  • 我怎么能到达这个元素,所以我可以appy上的.focus()?
  • 我可以避免使用document.getElemenntById()?

我试图使用“ElementRef”和“@ViewChild()”,但似乎我失去了一些东西:

 // ------ THE CLASS @ViewChild('tasknoteId') taskNoteRef:ElementRef; noteEditMode: boolean = false; get isShowNote (){ return !this.noteEditMode && this.todo.note ? true : false; } taskNote: string; toggleNoteEditMode () { this.noteEditMode = !this.noteEditMode; this.renderer.invokeElementMethod(this.taskNoteRef.nativeElement,'focus'); } // ------ THE COMPONENT <span class="the-insert"> <form [hidden]="!noteEditMode && todo.note"> <textarea #tasknoteId id="tasknote" name="tasknote" [(ngModel)]="todo.note" placeholder="{{ notePlaceholder }}" style="background-color:pink" (blur)="updateNote()" (click)="toggleNoteEditMode()" [autofocus]="noteEditMode" [innerHTML]="todo.note"> </textarea> </form> </span> 

如下所示,使用ViewChild#localvariable

 <textarea #someVar id="tasknote" name="tasknote" [(ngModel)]="taskNote" placeholder="{{ notePlaceholder }}" style="background-color: pink" (blur)="updateNote() ; noteEditMode = false " (click)="noteEditMode = false"> {{ todo.note }} </textarea> 

在组件中,

最老的方式

 import {ElementRef} from '@angular/core'; @ViewChild('someVar') el:ElementRef; ngAfterViewInit() { this.el.nativeElement.focus(); } 

老方法

 import {ElementRef} from '@angular/core'; @ViewChild('someVar') el:ElementRef; constructor(private rd: Renderer) {} ngAfterViewInit() { this.rd.invokeElementMethod(this.el.nativeElement,'focus'); } 

更新于22/03(三月)/ 2017

新方法

请注意,从Angular v4.0.0-rc.3(2017-03-10)几件事情已经改变。 由于Angular团队会弃用invokeElementMethod ,因此上面的代码不再可以使用。

打破变化

自4.0 rc.1:

将RendererV2重命名为Renderer2
将RendererTypeV2重命名为RendererType2
将RendererFactoryV2重命名为RendererFactory2

 import {ElementRef,Renderer2} from '@angular/core'; @ViewChild('someVar') el:ElementRef; constructor(private rd: Renderer2) {} ngAfterViewInit() { console.log(this.rd); this.el.nativeElement.focus(); //<<<=====same as oldest way } 

console.log(this.rd)会给你以下方法,你现在可以看到invokeElementMethod不存在。 附加IMG,但没有logging。

注意:您可以使用Rendere2以下方法来使用/不使用ViewChildvariables来执行许多操作。

在这里输入图像说明

更新(2017年9月10日):

请注意,原来的Renderer服务现在已经被弃用,以支持Renderer2

就像Renderer2官方文档一样。

此外,正如@GünterZöchbauer所指出的那样:

其实使用ElementRef就好了。 在Renderer2中使用ElementRef.nativeElement也没问题。 不鼓励直接访问ElementRef.nativeElement.xxx的属性。


您可以通过使用elementRef以及elementRef来实现此ViewChild 。 但是不build议使用elementRef因为:

  • 安全问题
  • 紧耦合

正如ng2文档所指出的那样。

使用elementRef (直接访问):

 export class MyComponent { constructor (private _elementRef : elementRef) { this._elementRef.nativeElement.querySelector('textarea').focus(); } } 

使用ViewChild更好的方法 ):

 <textarea #tasknote name="tasknote" [(ngModel)]="taskNote" placeholder="{{ notePlaceholder }}" style="background-color: pink" (blur)="updateNote() ; noteEditMode = false " (click)="noteEditMode = false"> {{ todo.note }} </textarea> // <-- changes id to local var export class MyComponent implements AfterViewInit { @ViewChild('tasknote') input: ElementRef; constructor(private renderer: Renderer2) {} //<-- changed to Renderer2 ngAfterViewInit() { this.input.nativeElement.focus(); } } 

Angular 2.0.0 Final:

我发现使用ViewChild setter是设置初始表单控件焦点的最可靠的方法:

 @ViewChild("myInput") set myInput(_input: ElementRef | undefined) { if (_input !== undefined) { setTimeout(() => { this._renderer.invokeElementMethod(_input.nativeElement, "focus"); }, 0); } } 

首先使用undefined值调用setter,然后使用初始化的ElementRef调用。

在这里工作的例子和完整的源代码: http : //plnkr.co/edit/u0sLLi?p=preview

使用TypeScript 2.0.3 Final / RTM,Angular 2.0.0 Final / RTM和Chrome 53.0.2785.116 m(64位)。