6

I can't figure out how to give a component a reference to its view, to do things like focus on input elements when the form is shown. I can't appear to inject Element or ng.core.ViewRef or ng.core.View into the constructor. How can I get access to the view?

In Angular 1, I would do this with $link.

Ben Dilts
  • 10,535
  • 16
  • 54
  • 85

3 Answers3

6

What you are looking for is probably ElementRef and its nativeElement field, but you should avoid accessing the DOM this way. I think a better way is to add a template variable like <input #inp> and the access it with @ViewChild('inp') input. In ngAfterViewInit input references the input element.

See also angular 2 / typescript : get hold of an element in the template

Community
  • 1
  • 1
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • That sounds about right. I'm struggling to find an example of that in ES5, though--know of an example or resource out there? – Ben Dilts Jan 02 '16 at 21:10
  • I don't know the details because I use only Dart, but this should show how to use DI in ES5 http://stackoverflow.com/questions/34532138/how-to-inject-custom-service-to-angular-component-in-plain-es5-javascript – Günter Zöchbauer Jan 02 '16 at 21:13
  • Oh, sorry, I can get an ElementRef, and thanks for the pointer there! I was actually looking for how to do `@ViewChild` in ES5 and couldn't turn anything up. – Ben Dilts Jan 02 '16 at 21:20
  • I found only `ng.core.ViewChild(myPredicate, 'myChildComponent', myComponent);` in https://angular.io/docs/js/latest/guide/cheatsheet.html – Günter Zöchbauer Jan 02 '16 at 21:30
5

I would also caution against direct DOM access in Angular, but here is an example of how to do it:

import {Component, ElementRef, Inject, OnInit} from '@angular/core';

declare var jQuery:any;

@Component({
    selector: 'jquery-integration',
    templateUrl: './components/jquery-integration/jquery-integration.html'
})
export class JqueryIntegration implements OnInit {

    constructor(private elementRef: ElementRef) {

    }

    ngOnInit() {
        jQuery(this.elementRef.nativeElement).find('.moving-box').draggable({containment:'#draggable-parent'});
    }
}

The key idea is to inject elementRef. You can then treat that as a regular DOM element. In my example here I am using jquery, but you can use standard DOM access as well.

More info: http://www.syntaxsuccess.com/viewarticle/using-jquery-with-angular-2.0

TGH
  • 38,769
  • 12
  • 102
  • 135
1

Just to expound on @Gunter's response above, you would use @ViewChild like this:

@ViewChild('myElem') myInput : ElementRef;
inputVal:string;

doSomething( input ){

  let startCursor = this.myInput.nativeElement.selectionStart;
  this.myInput.nativeElement.setSelectionRange(startCursor-1, startCursor-1);
}

html looks like this:

 <input #myElem type="text" [(ngModel)]="inputVal" maxlength="5" (keyup)="doSomething( myElem )" 
Jon
  • 7,848
  • 1
  • 40
  • 41